The Double Pointer of "The Sum of Three Numbers"

The study arrangement is based on leetcode15

At the beginning, I misunderstood the title and wrote it with double pointers, but repeated tuples appeared.

After reading the analysis, I found that it is not that simple and needs to be deduplicated.

Idea: Traversal + double pointer

1. Sort the array first, sort() defaults to the order from small to large;

2. One traversal

One traversal: Whenever the judgment condition of the double pointer ends, the i value is moved backward.

In order to avoid the following situation, it is necessary to perform the first deduplication processing (for example: nums[0]=nums[1])

 If the deduplication is judged as nums[i]==nums[i+1] continue; 

At this time, it can be seen that the condition (-1, -1, 2) will be lost.

Because the essence of deduplication is to prevent the occurrence of (-1, -1, 2) (-1, 2, -1) (2, -1, -1).

So, when i>0, nums[i]==nums[i-1] continue;

3. Two pointers left right

The judgment condition of the pointer is: left<right 

 When nums[i]+nums[left]+nums[right]>0, the right is shifted to the left;

 When nums[i]+nums[left]+nums[right]<0, left is shifted to the right;

When found, output the triplet.

A judgment is made below. If the next value of right / left is the same as the previous value, it is necessary to continue to compress the side with the same value, that is, this value is not desirable, and the range of left / right needs to be compressed.

while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;

When the values ​​are found to be different, the left and right can be compressed normally.

Code:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        vector<vector<int>>v;
       sort(nums.begin(),nums.end());
       for(int i=0;i<nums.size();i++)
       {
           if(nums[i]>0)
            return v;

            if(i>0&&nums[i]==nums[i-1])
            continue;/******/

            int left=i+1;
            int right=nums.size()-1;

           while(left<right)/*****/
           {
               if(nums[i]+nums[left]+nums[right]>0)
               {
                   right--;}
                else if(nums[i]+nums[left]+nums[right]<0)
                {
                    left++;
                }
                else
                 {
                     v.push_back({nums[i],nums[left],nums[right]});
                    while (right > left && nums[right] == nums[right - 1]) right--;
                    while (right > left && nums[left] == nums[left + 1]) left++;
                    right--;left++;
                 };
           }
        }
        return v;
    }
};

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324064102&siteId=291194637