Algorithm-the idea of solving the double pointer problem

Dual pointers algorithm, sometimes you feel very clever, solve a lot of problems, it is necessary to summarize, first of all two-pointer is a very broad concept, which is similar traversal i 和 jbut the difference is that the two pointers It moves at the same time, that is, it does not contribute complexity from O(N)to to O(N*N), so it is praised by many algorithm leaders, so based on this induction, we summarize the common solutions and routines of double pointers.

1. Question type induction

There are three types of questions, which are as follows:

  • Fast and slow pointers (press the two pointers that are not synchronized before and after)

  • Front and rear double pointers (one at the head, one at the tail, moving closer to the middle)

  • Fixed-interval pointers (two pointers with a spacing of i, i + k)

As mentioned earlier, these three pointers can be completed by traversing the array once, and their time complexity is lower than or equal to O(N), and the space complexity is O(1)because only two pointers are stored.

2. Common question types

2.1 Fast and slow pointers

Quite a classic question:

  • Determine whether the linked list has a ring-

Through the two pointers at different paces, move one after the other until the pointers coincide

https://leetcode.com/problems/linked-list-cycle/description , the code snippet is as follows:

public boolean hasCycle(ListNode head) {
    ListNode slow = head;
          ListNode fast = head;
    while (slow != null && fast != null) {
                 ListNode n = fast.next;
     fast = n == null ? null : n.next;
     if (slow == fast) {
         return true;
     }
                 slow = slow.next;
    }
    return false;
    }

The code is solved as follows:

public int findDuplicate(int[] nums) {
        // 将其看成是一个循环的链表,快慢指针循环
        int index1 = 0;
        int index2 = 0;
        do
        {
            index1 = nums[index1];
            index2 = nums[index2];
            index2 = nums[index2];

        }while (nums[index1] != nums[index2]);
        index1 = 0;
// 找出在哪个位置为起始点,可证必定在圆圈起点相遇
        while(index1 != index2){
            index1 = nums[index1];
            index2 = nums[index2];
        }
        return index1;
    }

2.2 Front and back end point pointers

  • Binary search

Binary search is a typical question type with front and back pointers. The code is as follows:

public static int binarySearch(int[] array, int targetElement) {
    int leftIndex = 0, rightIndex = array.length - 1, middleIndex = (leftIndex + rightIndex) / 2;

    while(leftIndex <= rightIndex) {
      int middleElement = array[middleIndex];
      if(targetElement < middleElement) {
        rightIndex = middleIndex - 1;
      }else if(targetElement > middleElement) {
        leftIndex = middleIndex + 1;
      }else {
        return middleIndex;
      }

      middleIndex = (leftIndex + rightIndex) / 2;
    }

    return -1;
  }

2.3 Pointers at fixed intervals

// 快指针q每次走2步,慢指针p每次走1步,当q走到末尾时p正好走到中间。

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode p = head, q = head;
        while (q != null && q.next != null) {
            q = q.next.next;
            p = p.next;
        }
        return p;
    }
}
    // 快慢指针,先让快指针走k步,然后两个指针同步走,当快指针走到头时,慢指针就是链表倒数第k个节点。

    public ListNode getKthFromEnd(ListNode head, int k) {

        ListNode frontNode = head, behindNode = head;
        while (frontNode != null && k > 0) {

            frontNode = frontNode.next;
            k--;
        }

        while (frontNode != null) {

            frontNode = frontNode.next;
            behindNode = behindNode.next;
        }

        return behindNode;
    }

3. Template summary

After reading the three codes, do you think it is very simple? Here is a summary of the three double pointer code templates

// 1.快慢指针
l = 0
r = 0
while 没有遍历完
  if 一定条件
    l += 1
  r += 1
return 合适的值

//2. 左右端点指针
l = 0
r = n - 1
while l < r
  if 找到了
    return 找到的值
  if 一定条件1
    l += 1
  else if  一定条件2
    r -= 1
return 没找到

//3. 固定间距指针
l = 0
r = k
while 没有遍历完
  自定义逻辑
  l += 1
  r += 1
return 合适的值

Wu Xie, Xiao San Ye, a little rookie in the background, big data, and artificial intelligence. Please pay attention to morefile

Guess you like

Origin blog.csdn.net/hu_lichao/article/details/110358651
Recommended