LeetCode-15-三数之和

LeetCode-15-三数之和

题目

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

思路

一开始我以为用动态规划之类的做,做不出来后看题解,发现其实就是在暴力的基础上进行优化;

具体是这样优化的,首先对数组排序,搜索时去重保证搜索到的结果不重复;

当a+b+c=0时,确定a后,在一个排序数组中确定b+c=-a可以通过双指针的方法,使得复杂度为O(N);

这是因为在排序数组中,b+c是一个定值,那么当前两数相加时,如果结果大于-a,则移动右指针使得数字减少;

如果结果小于-a,则移动左指针使得数字增加,和容器题的原理相类似,可以找出所有符合条件的数字;

代码中我的判重有点复杂,大概如下:

代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        typedef vector<int> vec;
        typedef vector<vec> matvec;
        int numsLength = nums.size();
        matvec ans;
        if (numsLength < 3) return ans;
        stable_sort(nums.begin(), nums.end());

        int preNum[3] = {0};
        int nowNum[3] = {0};

        for (int i=0; i<numsLength-2; i++) {
            nowNum[0] = nums[i];
            if (i != 0 && nowNum[0] == preNum[0]) continue;
            int x = i+1, y = numsLength-1;
            while (x < y) {
                nowNum[1] = nums[x]; nowNum[2] = nums[y];
                if (x!=i+1 && nowNum[1]==preNum[1]) {
                    x++; continue;
                }
                if (y!=numsLength-1 && nowNum[2]==preNum[2]) {
                    y--; continue;
                } 
                
                int res = nowNum[0]+nowNum[1]+nowNum[2];
                if (res < 0) {
                    x++;
                    preNum[1] = nowNum[1];
                }else if (res > 0){
                    y--;
                    preNum[2] = nowNum[2];
                }else {
                    vec arr(nowNum, nowNum+3);
                    ans.push_back(arr);
                    x++; y--;
                    preNum[1] = nowNum[1];
                    preNum[2] = nowNum[2];
                }

            }
            preNum[0] = nowNum[0];
        }
        return ans;
    }
};
posted @ 2020-08-02 16:38  樱花小猪  阅读(115)  评论(0编辑  收藏  举报