[Algorithm] The tricks and tricks about double pointers (1): Colliding pointers

1. Collision pointer

        The collision pointer consists of two pointers, pointing to the head and tail of the data respectively :

        The two pointers move from both ends respectively, and stop after finding a position that matches the answer . Colliding pointers are mainly used in the summation of ordered arrays . We use a topic to illustrate:

         Examples are as follows:

         According to the topic, the following conditions can be derived:

  • Arrays are arranged in ordered increasing order.
  • It is not possible to repeat the same element (that is, index1=index2 is unreasonable), but there is a relationship of 1<index1<index2<=numbers.Length .
  • Only corresponds to the only answer, that is, there may be more than one answer, only one of them needs to be output

        There are many solutions, using two for traversal, binary search, dynamic programming, etc., we use Example 1 to explain collision pointers:

         Initialize two head and tail pointers, pointing to the head and tail parts of the array respectively:

         Determine whether the addition of the current values ​​meets the target number, 2 + 15 = 17 > 9, and the tail pointer moves to the left :

        Let’s judge again: 2 + 11 = 13 > 9, continue to move the tail pointer to the left:

        2 + 7 = 9 == 9, output the result. Seeing this, it is estimated that many people will be confused . Why can the correct result be obtained in this way ? Let's use an example to analyze and illustrate:

         We enumerate all possible addition results:

         According to the second condition, we first exclude the case where index1 = index 2 :

         The black part is the eliminated part:

        Then eliminate the index1 > index2 part:

 

        The sum of the values ​​pointed by the current head and tail pointers is 17, marked in orange :

 

        2+15 = 17 < 22, indicating that the sum of the two numbers should increase further, and the number pointed to by the tail pointer is already the largest, so it is necessary to move the head pointer to the right to make the sum of the two numbers go up. Then it is deduced that the "2" pointed by the head pointer does not match the "6, 10, 12, 15" pointed by the tail pointer, because "15" is already the largest number that does not meet the target number, other numbers smaller than it Not to mention , the current head pointer moves to the right:

         The current situation is as follows:

         Then let’s infer, 6 + 15 = 21 < 22, indicating that the sum of the two numbers is not large enough, continue to increase, and the head pointer will move to the right:

        Exclude one item again as mentioned above:

        10 + 15 = 25 > 22, as long as you understand the principle mentioned above, it is also very simple to understand here, that is, the sum of the two numbers is greater than the target number, so the sum of the two numbers must be reduced, because the number pointed by the head pointer It is already the smallest , so you need to move the tail pointer to the left to reduce the sum of the two numbers:

         Exclude one item from Y:

        The last remaining number is the correct answer, from which we can draw the judgment conditions for the collision pointer :

  • The sum of the two numbers is greater than the target number, and the tail pointer moves to the left
  • The sum of the two numbers is less than the target number, and the head pointer moves to the right
  • The sum of the two numbers is equal to the target number, output the result

        The code for the collision implementation is as follows (reference):

        The next chapter will introduce the fast and slow pointers, which are used to quickly obtain intermediate numbers.

Guess you like

Origin blog.csdn.net/qq_41884002/article/details/128289581