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.
Steps:
(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 #division 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 #merge 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 else: 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