文章目录
- 题目描述
- 知识点
- 结果
- 实现
- 码前思考
- 代码实现
- 码后反思
- 参考思路
- 二刷代码
排序+双指针
这道题我没有做出来。。。
a+b+c = 0
,最直观的方法就是枚举a,b,c,也就是组合数 C n 3 C_n^3 Cn3,这样的会使时间复杂度达到 O ( n 3 ) O(n^3) O(n3),显然不可取;a+b+c = 0
,其实就是a = -b-c
。也就是对a
,我们要去寻找-b-c
即可。a
的 O ( n ) O(n) O(n)乘上枚举-b-c
的 O ( n 2 ) O(n^2) O(n2)),但是如果我们对原数组nums
进行排序,然后使用 双指针 ,那么枚举-b-c
的时间复杂度就变成了 O ( n ) O(n) O(n),这样总体时间复杂度就为 O ( n 2 ) O(n^2) O(n2)了;nums[k]
大于0时,我们就可以返回结果了,因为后面的数都不可能满足条件了。//采用O(n^2)+hash的解法
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
//特判一些特殊的情况:数组长度小于3的情况
int size = nums.size();
if(size < 3){
return res;
}
//通过排序来解决重复解的问题
sort(nums.begin(),nums.end());
//使用双指针来解决问题
for(int k=0;k<size;k++){
//用于已经排序,所以当当前数字nums[k]为整数时,肯定可以停止了
if(nums[k] > 0){
break;
}
//去除重复解,当nums[k]==nums[k-1]时,说明可以跳过这个k
if(k>0&&nums[k]==nums[k-1]){
continue;
}
//开始双指针操作
int target = 0 - nums[k];
int i= k+1;
int j= size-1;
//只要两个指针没有相遇,代表还在进行筛选
while(i<j){
if(nums[i]+nums[j] == target){
vector<int> tmp;
res.push_back({nums[k],nums[i],nums[j]});
//排除重复解的情况,即nums[i+1]==nums[i],nums[j-1]==nums[j]
while(i<j && nums[i+1] == nums[i]){
i++;
}
while(i<j && nums[j-1] == nums[j]){
j--;
}
i++;
j--;
}else if(nums[i]+nums[j] <target){//意味着i要右移
i++;
}else{ //意味着j要左移
j--;
}
}
}
return res;
}
};
a+b
,然后利用hash找-c
的,结果卡在重复解上,现在想想,只要排个序就能解决这个问题了,以后尝试一下,时间复杂度也是 O ( n 2 ) O(n^2) O(n2),这个想法就没有用到双指针了!LeetCode 第 15 号问题:三数之和
二刷的时候又忘记左右指针该怎么用了,
所谓左右指针用在数组上,通常都是需要是排序过后的数组。这道题目和之前的Two Sum的题目是一模一样的。
//采用双指针进行解题,使用的是左右指针
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
vector<vector<int>> res;
if(len<3){
return res;
}
sort(nums.begin(),nums.end());
for(int i=0;i<len;i++){
if(nums[i]>0){
break; //说明后面不可能了
}
if(i>0&&nums[i-1]==nums[i]){
continue;
}
int cur = nums[i];
int target = -cur;
int left = i+1;
int right = len-1;
while(left<right){
if(nums[left]+nums[right]==target){
vector<int> vt = {cur,nums[left],nums[right]};
res.push_back(vt);
//排除重复的情况
while(left<right&&nums[left+1]==nums[left]){
left++;
}
while(left<right&&nums[right-1]==nums[right]){
right--;
}
left++;
right--;
}else if(nums[left]+nums[right]<target){
left++;
}else{
right--;
}
}
}
return res;
}
};