20220225_ Datawhale 34_ leetcode_7 double pointer

Posted by ldougherty on Fri, 25 Feb 2022 09:24:46 +0100

Seven double pointers

1.1 Foundation

Collision pointer: refers to two pointers, left and right, pointing to the first element and the last element of the sequence respectively, and then the left pointer increases and the right decreases until the values of the two pointers Collide (i.e. left == right), or meet other special conditions.

(1) The two pointers left, right and left point to the first element Right points to the last element;
(2) Close to each other: left += 1, right -= 1
(3) Collision: left == right or other conditions jump out of the condition

It is generally used to solve the problem of ordered array or string

Speed pointer: refers to that two pointers start to traverse the sequence from the same side, and the moving step is fast and slow. A pointer that moves fast is called a fast pointer, and a pointer that moves slowly is called a slow pointer. The two pointers move at different speeds and strategies until the fast pointer moves to the end of the array, or the two pointers intersect, or other special conditions are met.

  • step
    (1) Two pointers: slow and fast. Generally, slow = 0 and fast = 1
    (2) The two pointers meet the conditions to move respectively
    (3) Fast pointer to the end or other conditions jump out

It is generally used to deal with the problem of moving and deleting elements in the array, or to judge whether there are rings and length problems in the linked list

Separate double pointers: the two pointers belong to different arrays / linked lists, and the two pointers move in the two arrays / linked lists respectively.

  • step
    (1) Two pointers left_1,left_2. Point to two arrays respectively, the first element of the linked list
    (2) Satisfy condition left_1,left_2 move right at the same time, or move only one of them
    (3) When one of the arrays or linked lists is traversed or other conditions are met, it will jump out

It is generally used to deal with the problems of ordered array merging, intersection and union

1.2 title

1.2.1 19 . Delete the penultimate node of the linked list

  • Idea: use the two pointers of fast and slow with a difference of n to traverse the linked list for solution
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0, head)
        fast, slow = head, dummy

        while n:            # Make the difference between fast and slow n nodes
            fast = fast.next
            n -= 1
        while fast:    
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return dummy.next

1.2.2 206 . Reverse linked list

  • Idea: establish cur, pre - > none solution
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

1.2.3 83 . Delete duplicate elements in the sorting linked list

  • Idea: establish a fast and slow double pointer slow, fast to solve the problem > > > fast is responsible for traversing the l linked list, and slow is responsible for recording non repeating elements
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head or not head.next:return head
        slow, fast = head, head
        while fast:
            if fast.val != slow.val:
                slow = slow.next
                slow.val = fast.val
            fast = fast.next
        slow.next = None
        return head

1.2.4 148 . Sort linked list

  • Idea: using merge sort > > > fast row and insertion will timeout > > > merge is divided into two steps: segmentation and merging > > > where segmentation is to design the speed pointer into two linked lists > > > merging is to merge two ordered linked lists. The same idea as above
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:return head 
        slow, fast = head, head.next
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        left_head, right_head = head, slow.next
        slow.next = None  # Realize segmentation

        def merge(left, right):
            if not left:return right
            if not right:return left
            if left.val <= right.val:
                left.next = merge(left.next, right)
                return left
                right.next = merge(left, right.next)
                return right
        #Recursive sorting
        return merge(self.sortList(left_head), self.sortList(right_head))

1.2.5 160 . Intersecting linked list

  • Idea: double pointer, complementary length > > > use P1 and P2 to point to two chain headers > > > on the premise of not finding the same node, if one node reaches None, point to the other chain header > > > make up the length gap and intersect sooner or later > > > if there is no same node, it will also stop when pointing to None at the same time
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        p1, p2 = headA, headB
        while p1 != p2:
            p1 = p1.next if p1 else headB
            p2 = p2.next if p2 else headA
        return p1

Topics: data structure leetcode linked list