LeetCode.15. 三数之和

52 阅读1分钟

题目


image.png

思路


  • 双指针
  • 双指针一般基于有序数组,可以方便移动指针,就像二分法一样。因此,先排序

代码

vector<vector<int>> threeSum(vector<int>& a) 
{
    int n = a.size();
    vector<vector<int>> ret;
    sort(a.begin(),a.end());
    for(const auto& c:a){
        cout << c << " ";
    }
    cout << endl;
    for(int s=0;s<=n-3;s++)// 0 -1 -1 1 1 
    {
        if(a[s] > 0)//剪枝,当前>0,后续不可能有答案,因为已经排序
        {
            return ret;
        }
        if(s>0 && a[s]==a[s-1])//剪枝,筛掉重复组合,cur==pre一定是会重复的,包括后面双指针的i,j
        {
            continue;
        }
        int i = s+1;
        int j = n-1;
        int target = -a[s];//双指针寻找的目标
        while(i<j)
        {
            int sum = a[i]+a[j];
            if(sum == target)
            {
                ret.push_back({a[s],a[i],a[j]});
                i++;
                j--;
                while(i<j && a[i]==a[i-1]){//筛掉重复组合
                    i++;
                }
                while(i<j && a[j]==a[j+1]){
                    j--;
                }
            }
            else if(sum < target)
            {
                i++;//这里后面不需要while处理重复问题,后续若仍是当前元素,则sum不变,仍会判断到此,相当于多了一次判断
            }
            else if(sum > target)
            {
                j--;
            }
        }
    }
    return ret;
}

总结


  • 双指针,找目标问题,经常结合排序、有序。双指针在移动过程,一般需要基于某种条件,就像二分法,有序数组,有大小关系才能促成 二分的区间更新