24. 两两交换链表中的节点
构造虚拟节点并从虚拟节点开始遍历
注意操作的先后顺序 按新的链表顺序进行赋值(节点更改)
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return
dummy = ListNode()
dummy.next = head
pre = dummy
while pre.next and pre.next.next:
cur = pre.next
post = pre.next.next.next
pre.next = pre.next.next
pre.next.next = cur
cur.next = post
pre = pre.next.next
return dummy.next
19. 删除链表的倒数第 N 个结点
快慢指针的思路,通过快指针先走n步,定位倒数第n个节点
需要注意特殊情况(只有一个节点)
且需要用虚拟节点来获取结果
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
if not head:
return
fast = head
while n:
fast = fast.next
n -= 1
pre = ListNode()
pre.next = head
slow = pre
while fast:
fast = fast.next
slow = slow.next
if slow.next:
slow.next = slow.next.next
else:
slow = None
return pre.next
面试题 02.07. 链表相交
本质是指针会分别经过A,B
A(B)单次遍历完后,遍历B(A),因此两者的位置会达到一致
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
curA = headA
curB = headB
while curA or curB:
if curA == curB:
return curA
curA = curA.next if curA else headB
curB = curB.next if curB else headA
return None
142. 环形链表 II
快慢指针
fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return
slow = fast = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
return