Algorithm Notes - Two Pointers

Algorithm Notes - Two Pointers

Double pointers use two pointers to scan objects. Generally, there are two types of pointers: fast and slow pointers and left and right pointers. The fast and slow pointers start from one side and move to the other side at the same time but at different speeds. The left and right pointers move from two sides to each other respectively. move

The content of the double pointer is not much, but it is very flexible to use, and you need to do more questions to experience the ideas

Common uses of fast and slow pointers

1. Determine whether the linked list has a cycle

The characteristic of a singly linked list is that each node only knows the next node, so a pointer cannot determine whether the linked list contains a cycle.

If there is no ring in the linked list, then the pointer will eventually encounter the null pointer null, indicating that the linked list is at the end.
But if there is a ring in the linked list, then this pointer will fall into an infinite loop, because there is no null pointer in the ring array as a tail node.

The classic solution is to use two pointers, one for advancing two steps at a time, and one for advancing one step at a time. If there is no ring, the faster pointer will eventually encounter null, indicating that the linked list does not contain a ring; if there is a ring, the fast pointer will eventually exceed the slow pointer one circle, and meet the slow pointer, indicating that the linked list contains a ring.

2. Knowing that the linked list has a ring, return the starting position of the ring

Reference article
When the fast and slow pointers meet, let any one of them point to the head of the linked list, and then let the two pointers advance at the same speed, and the node position where they meet again is the position where the ring starts.
insert image description here

  1. When we meet for the first time, assuming that the slow pointer has taken k steps, then the fast pointer must have taken 2k steps, which means that the slow has taken k steps, which is the length of the ring.
  2. Assuming that the distance between the encounter point and the starting point of the ring is m (shown by the orange curve), then the distance between the starting point of the ring and the head node head is km. This is because the slow pointer takes k steps, which includes the head node to the start of the ring (green straight line), and the ring start to the meeting point (orange), and the distance between the latter is m, then the start of the ring is the same as The distance of the head node head is km. But because the length of the entire ring is k, continuing km steps from the meeting point (the green curve part) will also reach the start of the ring, which is exactly the same distance as the head node and the start of the ring.
  3. So we only need to re-point either of the fast and slow pointers to the head, and then the two pointers advance at the same speed. After the km step, the two pointers will meet, and the meeting point is the starting point of the ring.

3. Find the midpoint of the linked list

Similar to the above idea, we can also make the fast pointer advance two steps at a time, and the slow pointer advance one step at a time. When the fast pointer reaches the end of the linked list, the slow pointer is in the middle of the linked list.

4. Find the k-th element from the bottom of the linked list

Our idea is to use the fast and slow pointers, let the fast pointer take k steps first, and then the fast and slow pointers start to advance at the same speed. In this way, when the fast pointer goes to null at the end of the linked list, the position of the slow pointer is the kth last linked list node (for simplicity, it is assumed that k will not exceed the length of the linked list)

5. Sliding window

For example, to find the longest substring without repeated characters,
the sliding window algorithm is used. The right border of the sliding window is continuously moved to the right. As long as there are no repeated characters, the window border continues to expand to the right. Once a repeating character appears, the left border needs to be reduced until the repeated character moves beyond the left border, and then the right border of the sliding window is moved on. By analogy, each movement needs to calculate the current length, and determine whether the maximum length needs to be updated, and the final maximum value is what the question requires.

Reference article (with code)

Common usage of left and right pointers

binary search

In binary search, we define a left and a right respectively to point to the corresponding element, which is also a kind of left and right pointer

There are many uses of double pointers, you can continue to deepen your understanding through the following examples

example

82. Delete duplicate elements in sorted linked list II
15. Sum of three numbers
844. Compare strings with backspaces
986. Intersection of interval lists
11. The container that holds the most water

Guess you like

Origin blog.csdn.net/shn111/article/details/123211014