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;
}
};