时间复杂度O(n²)
解题思路
- 想了10多分钟完全就没思路,只好看题解思路,懂了思路代码没什么坑,直接就写出来了;
- 先排序,数组的有序性方便去重;
- 每次固定一个数字作为第一个数,在其右边用双指针找第二第三个数。如果三个数加起来小于0,因为数组是有序的并且第一个数是固定的,那么想要得到等于0的结果只能将双指针中的左指针往右移找更大的数。同理如果三个数加起来大于0,则移动右指针。
代码思路
- 排除特殊情况;
- 排序;
- 第一个while明确,第一个数不能和上一次的第一个数相同,不然会出现重复结果;
- 获取左右指针,进入第二个while循环,结束条件是左右指针重叠;
- 判断时有三种情况,三数之和大于0,三数之和小于0,三数之和等于0。前两种分别移动左右指针即可。第三种,作为结果放进结果数组,并后续更新左右指针,更新时进行去重,这是就利用到了数组有序的优势,可以去重。
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
if(nums.size()<3) return result;
sort(nums.begin(),nums.end());
for(int i=0; i<nums.size(); i++){
while(i && i<nums.size() && nums[i]==nums[i-1]) i++;
int left=i+1,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 if(nums[i]+nums[left]+nums[right]==0){
vector<int> resultIndex;
resultIndex.push_back(nums[i]);
resultIndex.push_back(nums[left]);
resultIndex.push_back(nums[right]);
result.push_back(resultIndex);
resultIndex.clear();
do{
left++;
}while(left<right && nums[left]==nums[left-1]);
do{
right--;
}while(left<right && nums[right]==nums[right+1]);
}
}
}
return result;
}
};
总结
- 第一次完完全全的没有思路,想到的暴力也不会去重,排序去重这个真的很巧妙。