算法训练营 Day 04| 链表2

64 阅读1分钟

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