15. 三数之和
难度中等2128收藏分享切换为英文关注反馈
给你一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4];
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
这是一道非常典型的题目,值得我们细细研究。题意十分简单,在一个数组nums[]中找到满足三数之和为0的所有情况,将它们保存在一个vector<vector<int> >类型的变量中返回。直观来看,用暴力解法分析,用三个for循环遍历所有可能性,代码看起来如下:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> v1;
if( nums.empty())
{
return v1;
}
int x=0;
int len = nums.size();
for(int i=0;i<len-2;i++)
{
for(int j=i+1;j<len-1;j++)
{
for(int k=j+1;k<len;k++)
{
if(nums[i]+ nums[j]+ nums[k] == 0)
{
vector<int> v_temp{nums[i], nums[j],nums[k]};
v1.push_back(v_temp);
}
}
}
}
return v1;
}
};
这个算法是最简单时间复杂度为O[n^3],并且容易懂得,但是有一个不bug。不能去除重复的选项。
正确解法,使用双指针法
1、先排除不合格的各种情况
2、把数列排序,从小到大
3、使用双指针法m和 k,由nums[i]+ nums[k]+ nums[m] == 0 转换成
nums[m]+ nums[k] == -nums[i] 转换成 nums[m]+ nums[k] == -nums[i]
每次(m < nums.size()-1 && nums[m] == nums[m+1]) || nums[k]+nums[m]> -nums[i] m--
(k > i+1 && nums[k] == nums[k-1]) || nums[k]+nums[m] < target k++
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int>> result;
if(nums.empty())//这一行不加会报错Line 924: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h)
{
return result;
}
sort(nums.begin(),nums.end());
if(nums[0] > 0 || nums.size() < 3 || nums[nums.size()-1] < 0)
{
return result;
}
for(int i = 0;i<nums.size()-1;++i)
{
if(nums[i] > 0)
{
break;
}
if(i>0 && nums[i] == nums[i-1])
{
continue;
}
int target = 0 - nums[i];
int k = i+1;
int m = nums.size()-1;
while(m > k)
{
if(nums[k] > target)
{
break;
}
if((m < nums.size()-1 && nums[m] == nums[m+1]) || nums[k]+nums[m]> target)
{
--m;
}else if((k > i+1 && nums[k] == nums[k-1]) || nums[k]+nums[m] < target)
{
++k;
}else
{
vector<int> temp_v;
temp_v.push_back(nums[i]);
temp_v.push_back(nums[k]);
temp_v.push_back(nums[m]);
result.push_back(temp_v);
++k;
}
}
}
return result;
}
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)