双指针

Posted 张乐乐章

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双指针相关的知识,希望对你有一定的参考价值。

 

快慢指针:

141. Linked List Cycle(快慢指针---判断链表是否有环)

 142. Linked List Cycle II(快慢指针--找出链表相交的节点)

876. 链表的中间结点

 1 class Solution {
 2 public:
 3     ListNode* middleNode(ListNode* head) {
 4         ListNode* slow = head;
 5         ListNode* fast = head;
 6         while(slow != NULL && fast != NULL && fast->next != NULL) {
 7             slow = slow->next;
 8             fast = fast->next->next;
 9         }
10         return slow;
11     }
12 };

19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)

 

 

 

左右指针

 

二分法其实也算左右指针

 

167. Two Sum II - Input array is sorted(双指针)

 

344. 反转字符串

 1 class Solution {
 2 public:
 3     void reverseString(vector<char>& s) {
 4         int low = 0;
 5         int high = s.size() -1;
 6         while(low <= high) {
 7             char t = s[low];
 8             s[low] = s[high];
 9             s[high] = t;
10             low++;
11             high--;
12         }
13     }
14 };

 

11. Container With Most Water(装最多的水 双指针)

那边矮扔掉哪边

 

 1 class Solution {
 2 public:
 3     int maxArea(vector<int>& height) {
 4         int low = 0;
 5         int high = height.size() -1;
 6         int res = 0;
 7         while(low < high) {
 8             int cur_res = min(height[low],height[high]) * (high-low);
 9             res = max(cur_res,res);
10             if(height[low]<height[high]) low++;
11             else high--;
12         }
13         return res;
14     }
15 };

 

 15. 3Sum(字典) (双指针)

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         
 5         sort(nums.begin(),nums.end());
 6         vector<vector<int>> res;
 7         if (nums.size() < 3) return res;
 8         for (int i = 0;i < nums.size()-1;++i) {
 9             if(i>0 && nums[i]==nums[i-1]) continue;
10             int low = i+1;
11             int high = nums.size() -1;
12             while(low < high) {
13                 int sum = nums[i] + nums[low] + nums[high];
14                 if (sum == 0) {
15                     res.emplace_back(vector<int>({nums[i],nums[low],nums[high]}));
16                     while(low<high && nums[low+1]== nums[low]) low++;
17                     while(low<high && nums[high-1]== nums[high]) high--;
18                     low++;
19                     high--;
20                 } else if (sum > 0) {
21                     high--;
22                 } else if (sum < 0) {
23                     low++;
24                 }
25             }
26         }
27         return res;
28     }
29 };

 

 

16. 3Sum Closest(双指针)

 

18. 4Sum(双指针 注意答案去重)

 

 26. Remove Duplicates from Sorted Array(左右双指针)

删除重复的元素,1 1 1 2 2 3---》1 2 3

 1 class Solution {
 2 public:
 3     int removeDuplicates(vector<int>& nums) {
 4         int low = 0;
 5         int high = 0;
 6         if (nums.size() == 0) return 0;
 7         while(high < nums.size()) {
 8             if(nums[low]!=nums[high]) {
 9                 low++;
10                 nums[low] = nums[high];
11                 high++;
12             } else {
13                 high++;
14             }
15         }
16         return low+1; //题目要求返回长度,而不是索引
17     }
18 };

 

83. Remove Duplicates from Sorted List(排序链表去重. 左右双指针)

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* low = head;
        ListNode* high = head;
        if (head == nullptr) return nullptr;
        while(high != nullptr) {
            if(low->val!= high->val) {
                low->next = high;
                low = low->next;
                //low = low->next;
                //low->val = high->val;
            }
            high = high->next;
        }
        return head;
    }
};

 

 

 

27. Remove Element(双指针)

删除指定的元素 1 1 1 2 2 3(指定2)--》1 1 1 3

 

注意这里和有序数组去重的解法有一个重要不同,我们这里是先给 nums[slow] 赋值然后再给 slow++,这样可以保证 nums[0..slow-1] 是不包含值为 val 的元素的,最后的结果数组长度就是 slow

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int low = 0;
        int high = 0;
        while(high < nums.size()) {
            if (nums[high]!=val) {
                nums[low] =nums[high];
                low++;
                high++;
            }
            else {
                high++;
            }
        }
        return low;
    }
};

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

 1 class Solution {
 2 public:
 3     void moveZeroes(vector<int>& nums) {
 4         int low = 0;
 5         int high = 0;
 6         while(high < nums.size()) {
 7             if(nums[high]!=0) {
 8                 nums[low] = nums[high];
 9                 low++;
10             }
11             high++;
12         }
13         for(int i =low;i<nums.size();++i) {
14             nums[i] = 0;
15         }
16     }
17 };

 

80. Remove Duplicates from Sorted Array II(双指针)

删除重复的元素,1 1 1 2 2 3---》1 1 2 2 3 (每个元素最多2个)

 

因为最多允许两个重复元素,并且 slow - 2 位置是上上次放置了元素的位置,所以让 nums[fast] 跟 nums[slow - 2] 进行比较。每次都是只允许最多两个元素出现重复,这两个元素的位置在 slow - 1 和 slow - 2.

 1 class Solution {
 2 public:
 3     int removeDuplicates(vector<int>& nums) {
 4         if (nums.size() < 2) return nums.size();
 5         int low = 2;
 6         int high = 2;
 7         while(high < nums.size()) {
 8             if (nums[high] != nums[low-2]) {
 9                 nums[low] = nums[high];
10                 low++;
11             }
12             high++;
13         }
14         return low;
15     }
16 };

 

 

76. Minimum Window Substring(hard 双指针)

 209. Minimum Size Subarray Sum(双指针)

以上是关于双指针的主要内容,如果未能解决你的问题,请参考以下文章

更新:C++ 指针片段

在链表中添加节点时使用双指针的原因是啥?

双指针

片段中的 EditText 上的空指针异常 [重复]

常用算法-双指针系列

C中带有双指针的代码