24. 兩兩交換連結串列中的節點
用虛擬頭結點,這樣會方便很多。
本題連結串列操作就比較複雜了,建議大家先看影片,影片裡我講解了注意事項,為什麼需要temp儲存臨時節點。
題目連結/文章講解/影片講解: https://programmercarl.com/0024.兩兩交換連結串列中的節點.html
思考
需要設定一個虛擬頭節點,方便操作。
最好先畫下圖,明確指標斷開重連的步驟,哪些節點需要用臨時變數存起來。
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode()
dummy.next = head
cur = dummy
while cur.next and cur.next.next:
temp = cur.next
temp1 = cur.next.next.next
cur.next = cur.next.next
cur.next.next = temp
temp.next = temp1
cur = temp
return dummy.next
19.刪除連結串列的倒數第N個節點
雙指標的操作,要注意,刪除第N個節點,那麼我們當前遍歷的指標一定要指向 第N個節點的前一個節點,建議先看影片。
題目連結/文章講解/影片講解:https://programmercarl.com/0019.刪除連結串列的倒數第N個節點.html
思考
設定一個虛擬頭結點,方便只有一個節點時進行操作。雙指標,間隔n-1步,正好可以取到倒數第n個節點的前一個節點,方便刪除。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummp = ListNode(0)
dummp.next = head
fast = dummp
slow = dummp
i = 0
while fast:
fast = fast.next
if i > n:
slow = slow.next
i+=1
slow.next = slow.next.next
return dummp.next
面試題 02.07. 連結串列相交
本題沒有影片講解,大家注意 數值相同,不代表指標相同。
題目連結/文章講解:https://programmercarl.com/面試題02.07.連結串列相交.html
思考
A遍歷完後,接著遍歷B。B遍歷完後,接著遍歷A。
相交的時候,正好兩種路徑走的步長一樣。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
curA = headA
curB = headB
is_A = True
is_B = True
while curA and curB:
if curA == curB:
return curA
if curA.next is None and is_A:
curA = headB
is_A = False
else:
curA = curA.next
if curB.next is None and is_B:
curB = headA
is_B = False
else:
curB = curB.next
return None
上面的程式碼太冗餘了,實際上while的條件直接判斷curA和curB是否相等就好了,如果相交,則在交點退出,如果不想交,正好在連結末尾退出。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
cur_a = headA
cur_b = headB
while cur_a != cur_b:
if cur_a:
cur_a = cur_a.next
else:
cur_a = headB
if cur_b:
cur_b = cur_b.next
else:
cur_b = headA
return cur_a
142.環形連結串列II
算是連結串列比較有難度的題目,需要多花點時間理解 確定環和找環入口,建議先看影片。
題目連結/文章講解/影片講解:https://programmercarl.com/0142.環形連結串列II.html
思考
快慢指標,慢指標速度是1,快指標速度是2,速度差是1,如果有環,一定會在環內相遇。
x和z的關係如下,
x = (n - 1) (y + z) + z
在相遇點和頭結點同時遍歷的話,一定會在入口處再次相遇。(從相遇點出發的遍歷可能會多跑n-1圈)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow = head
fast = head
while True:
if fast and fast.next:
fast = fast.next.next
else:
return None
slow = slow.next
if slow == fast:
break
# 相交
new_slow = head
while new_slow != slow:
new_slow = new_slow.next
slow = slow.next
return slow