16
class Solution {
public:
vector> threeSum(vector& nums) {
sort(nums.begin(), nums.end());
vector> res;
int len = nums.size();
for(int k = 0; k < len; ++k){
if(nums[k] > 0)
break;
if(k > 0 && nums[k] == nums[k-1])
continue;
int tmp = -nums[k];
int i = k+1;
int j = len-1;
while(i < j){
if(nums[i] + nums[j] == tmp){
res.push_back({nums[k], nums[i], nums[j]});
while(i < j && nums[i] == nums[i+1])++i;
while(i < j && nums[j] == nums[j-1])--j;
++i; --j;
}else if(nums[i] + nums[j] < tmp){
++i;
}else if(nums[i] + nums[j] > tmp){
--j;
}
}
}
return res;
}
};
发表于 2018-04-04 11:57:01
回复(2)
6
class Solution {
public:
vector > threeSum(vector &num)
{
/// 先排序再双指针进行夹逼
int len = num.size();
vector> res;
if(len==0) return res;
sort(num.begin(),num.end());
for(int i=0;i
{
int sum = -num[i];
int j=i+1,k=len-1;
while(j
{
int cur = num[j] + num[k];
if(cur==sum)
{
vector temp;
temp.push_back(num[i]);
temp.push_back(num[j]);
temp.push_back(num[k]);
res.push_back(temp);
/// skip same num[j],num[k]
while(j
j++;
while(j
k--;
}
else if(cur
++j;
else
--k;
}
/// skip same num[i]
while(i
i++;
}
return res;
}
};
发表于 2017-07-13 14:58:10
回复(0)
14
/**
* (1)首先对数组进行排序(从小到大)
* (2)依次取出第 i 个数(i从0开始),并且不重复的选取(跳过重复的数)
* (3)这样问题就转换为 2 个数求和的问题(可以用双指针解决方法)
* 2 数求和问题
* (4)定义两个指针:左指针(left) 和 右指针(right)
* (5)找出固定 left, 此时left所指的位置为数组中最小数,再找到两个数和 不大于 target 的最大 right 的位置
* (6)调整 left 的位置(后移),求解和是否为 target O(n)
* (7)时间复杂度:O(nlogn) + O(n)
*/
class Solution {
public:
vector > threeSum(vector &num) {
//数组排序(小-->大)
sort(num.begin(), num.end());
//结果集合
vector> ans;
//先依次取出一个数,转换为 2 数求和问题
for (int i = 0; i < num.size(); i++){
if ( i == 0 || num[i] != num[i-1]){//防止重复
//定义左右指针
int left = i + 1, right = num.size() - 1;
// 2 数求和问题,固定left, 找出最大的right
while (left < right){
//right 左移, 减小 num[right] 的值
while (left < right && num[i] + num[left] + num[right] > 0) right --;
if (left < right && num[i] + num[left] + num[right] == 0){
//保存当前结果
vector temp(3);
temp[0] = num[i];
temp[1] = num[left];
temp[2] = num[right];
//保存到最终的结果中
ans.push_back(temp);
//右移 left (去除重复)
while (left < right && num[left] == temp[1]) left ++;
} else { // num[i] + num[left] + num[right] < 0的情况,left右移,增大num[left]的值
left++;
}
}
}
}
return ans;
}
};
发表于 2016-06-13 16:24:47
回复(7)
7
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int[] num = {-2, 0, 1, 1, 2};
System.out.println(new Solution().threeSum(num));
}
public ArrayList> threeSum(int[] num) {
ArrayList> result = new ArrayList<>();
if (num == null) {
return result;
}
//排序
Arrays.sort(num);
int sum, left, right;
for (int i = 0; i < num.length - 2; i++) {
//避免重复, 比如前面计算了以-1开头,后面就不用计算了
if (i != 0 && num[i] == num[i - 1]) {
continue;
}
left = i + 1;
right = num.length - 1;
/**
* 固定一个数,从后面的数中选出两个数,因为数组是有序的,所以可以
* 用两个数组下标left和right,left指向当前元素的后一个位置,right指向最后一个位置
* 三个数相加的和等于0时,加入解集;
* 小于0时,把left往右边移动;
* 大于0时,把right往左边移动;
*/
while (left < right) {
sum = num[left] + num[right];
if (sum + num[i] == 0) {
ArrayList solution = new ArrayList<>();
solution.add(num[i]);
solution.add(num[left]);
solution.add(num[right]);
result.add(solution);
left++;
right--;
//这个优化必须加,不加时间超限,其实这个优化也没太大作用嘛
while (left < right && num[left] == num[left - 1]) {
left++;
}
while (left < right && num[right] == num[right + 1]) {
right--;
}
} else if (sum + num[i] < 0) {
left++;
} else {
right--;
}
}
}
return result;
}
}
编辑于 2017-08-12 14:29:26
回复(7)
4
// 程序可以用来解决多个数求和等于给定target的问题
// 使用的是DFS思想, 从左到右不断选择一个数,选择一条完整的路径并判断是否等于target
// 使用了剪枝来加快速度
// 对于重复的问题,使用的是set来对vector型的变量去重
// (比unique那种要快,而且不需要对结果重新排序)
// 为了避免DFS造成的大量的空间占用,传递都为引用类型,需要恢复现场(push和pop)
class Solution {
int N = 3;
public:
// 使用DFS的思想来完成
vector > threeSum(vector &num, int target=0) {
vector> result;
set> res;
vector vi;
sort(num.begin(), num.end());
dfs(res, vi, num, target, 0, 0);
// sort(result.begin(), result.end());
// result.erase(unique(result.begin(),result.end()),result.end());
for(auto a:res){
result.push_back(a);
}
return result;
}
void dfs(set> &res, vector &vi, vector &num, int target, int start, int cnt) {
if(cnt==N){
if(target==0){
res.insert(vi);
}
return;
}
// 选择一个开始位置
for(int i=start;i
// cnt表示已经累加的数, 加上当前数的话, 还有n-cnt-1个数
// 所需要的是target-num[i], 这个数一定要大于(N-cnt-1)*num[i])才行
if(target-num[i]
break;
}
// 选择了某条通路
vi.push_back(num[i]);
// 在该通路上继续前行
dfs(res,vi, num, target-num[i] , i+1, cnt+1);
// 恢复现场, 走完了某条通路, 需要恢复现场
vi.pop_back();
}
}
};
发表于 2018-06-28 10:02:28
回复(2)
2
class Solution:
def threeSum(self , num ):
# write code here
len_num=len(num)
if len_num<3:
return []
lis1=[]
lis2=[]
for i in range(len_num-2):
a=num[i]
for j in range(i+1,len_num-1):
b=num[j]
c=a+b
if -c in num[j+1:]:
lis2=sorted([a,b,-c])
if lis2 not in lis1:
lis1.append(lis2)
return sorted(lis1)
发表于 2020-08-29 22:07:48
回复(0)
2
class Solution {
public:
vector > threeSum(vector &num) {
vector> result;
sort(num.begin(), num.end());
for(int i=0; i
{
if(i!=0 && num[i]==num[i-1])
continue;
int j=i+1;
int k = num.size()-1;
while(j
{
if(num[i]+num[j]+num[k]==0)
{
vector temp{num[i],num[j],num[k]};
result.push_back(temp);
++j;
while(j
++j;
}
else if(num[i]+num[j]+num[k]<0)
++j;
else
--k;
}
}
return result;
}
};
发表于 2018-07-09 16:07:07
回复(1)
2
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 15.Three sum
* 三数之和
*/
public class Solution {
public List> threeSum(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
List> result = new ArrayList<>();
for (int i = 0; i < n-2; i++) {
if (i>0 && nums[i-1] == nums[i]){
continue;
}
int j = i + 1;
int k = n - 1;
while (j < k) {
if (nums[i] + nums[j] + nums[k] < 0){
// 去重复
while (j < k && nums[j] == nums[j+1]) {
j++;
}
j++;
}
else if (nums[i] + nums[j] + nums[k] > 0){
// 去重复
while (k > j && nums[k] == nums[k-1]) {
k--;
}
k--;
}
else{
List item = new ArrayList<>();
item.add(nums[i]);
item.add(nums[j]);
item.add(nums[k]);
result.add(item);
// 去重复
while (j < k && nums[j] == nums[j+1]) {
j++;
}
while (k > j && nums[k] == nums[k-1]) {
k--;
}
j++;
k--;
}
}
}
return result;
}
public static void main(String[] args){
Solution solution = new Solution();
int[] nums = new int[]{-1, 0, 1, 2, -1, -4};
List> result = solution.threeSum(nums);
System.out.println(result);
}
}
发表于 2018-05-14 21:43:40
回复(0)
1
import java.util.*;
public class Solution {
public ArrayList> threeSum(int[] num) {
Arrays.sort(num);//重排,后面就不用排了
ArrayList> res = new ArrayList<>();
//定义三个指针:left,mid,right,固定三个值,不去重会超时
for(int left = 0;left < num.length-2;left++){//固定left位置
if(num[left] <= 0){//因为重新排序过,只有小于等于0才判断
for(int right = num.length-1;right >left;right--){//固定right位置
for(int mid = right - 1;mid < right && mid >left;mid--){//遍历mid,left
if((num[left] + num[right] + num[mid]) == 0){//如果符合条件,加入到res结果里
ArrayList sol = new ArrayList<>();
sol.add(num[left]);
sol.add(num[mid]);
sol.add(num[right]);
res.add(sol);
//去重
while(num[mid-1] == num[mid] && (mid-1) < right && (mid-1) >left) {
mid--;
}
}
}
//去重
while(num[right-1] == num[right] && right-1 >left){
right--;
}
}
}else{
break;
}
//去重
while(num[left+1] == num[left] && (left+1) < num.length-2){
left++;
}
}
return res;
}
}
发表于 2021-04-05 18:35:42
回复(0)
1
思路:双指针
import java.util.*; public class Solution {
public ArrayList> threeSum(int[] num) {
//双指针
Arrays.sort(num);
ArrayList> ans=new ArrayList> ();
for(int i=0;i
if(i!=0&&num[i]==num[i-1]) continue;
int left=i+1;
int right=num.length-1;
while(left
if(num[i]+num[left]+num[right]==0) {
ArrayList list=new ArrayList<> ();
list.add(num[i]);
list.add(num[left]);
list.add(num[right]);
ans.add(list);
left++;
right--;
while(left
while(left
}
if(num[i]+num[left]+num[right]<0) left++;
if(num[i]+num[left]+num[right]>0) right--;
}
}
return ans;
}
}
发表于 2021-03-15 10:37:51
回复(0)
1
通过了,我这算是暴力解法吗 import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public ArrayList> threeSum(int[] num) {
Arrays.sort(num);
int sum=0;
ArrayList> res = new ArrayList<>();
for(int i=0;i
int start=i+1;
int end=num.length-1;
while(start
sum=num[i]+num[start]+num[end];
if(sum>0)end--;
else if(sum<0) start++;
else {
ArrayList result = new ArrayList<>();
result.add(num[i]);
result.add(num[start]);
result.add(num[end]);
if(!res.contains(result)){
res.add(result);
}
start++;
end--;
}
}
}
return res;
}
}
编辑于 2020-10-10 11:57:57
回复(0)
1
import java.util.Arrays;
import java.util.ArrayList;
public class Solution {
public ArrayList> threeSum(int[] num) {
ArrayList> lists = new ArrayList<>();
if (num == null || num.length == 0) {
return lists;
}
Arrays.sort(num);
for (int k = 0; k < num.length - 2; k++) {
if (num[k] > 0) {
break;
}
if (k > 0 && num[k] == num[k - 1]) {
continue;
}
int i = k + 1;
int j = num.length - 1;
while (i < j) {
int sum = num[k] + num[i] + num[j];
if (sum > 0) {
while (j > i && num[j] == num[--j]);
} else if (sum < 0) {
while (i < j && num[i] == num[++i]);
} else {
ArrayList list = new ArrayList<>();
list.add(num[k]);
list.add(num[i]);
list.add(num[j]);
lists.add(list);
while (i < j && num[i] == num[++i]);
while (j > i && num[j] == num[--j]);
}
}
}
return lists;
}
}
发表于 2019-11-04 10:49:39
回复(0)
1
// 高效版
class Solution {
public:
vector> threeSum(vector& nums) {
vector> res;
if (nums.size() < 3)
return res;
sort(nums.begin(), nums.end());
if (nums.back() < 0 || nums.front() > 0)
return res;
for (auto i = nums.begin(); i != nums.end() - 2;) {
auto j = i + 1, k = nums.end() - 1;
while (j < k) {
int val = *i + *j + *k;
if (val == 0) {
res.push_back({*i, *j, *k});
while (++j < k && *j == *(j - 1));
while (--k > j && *k == *(k + 1));
}
else if (val < 0)
while (++j != k && *j == *(j - 1));
else if (val > 0)
while (--k != j && *k == *(k + 1));
}
while (++i != nums.end() - 2 && *i == *(i - 1));
}
return res;
}
};
// 低效版
class Solution {
public:
vector> threeSum(vector& nums) {
vector> res;
if (nums.size() < 3)
return res;
sort(nums.begin(), nums.end());
for (auto i = nums.begin(); i != nums.end() - 2;) {
for (auto j = i + 1; j != nums.end() - 1;) {
for (auto k = j + 1; k != nums.end();) {
if (*i + *j + *k == 0)
res.push_back({*i, *j, *k});
while (++k != nums.end() && *k == *(k - 1));
}
while (++j != nums.end() - 1 && *j == *(j - 1));
}
while (++i != nums.end() - 2 && *i == *(i - 1));
}
return res;
}
};
编辑于 2019-04-03 12:42:54
回复(0)
1
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ThreeSum { public static void main(String[] args) { threeSum(new int[]{1,-1,0}); } public static ArrayList> threeSum(int[] num) {
Arrays.sort(num);
int n=num.length;
ArrayList> result = new ArrayList>();
for(int i=0;i
if(i!=0&&num[i-1]==num[i]){
continue;
}
int start=i+1,end=n-1;
while(start
if(num[i]+num[start]+num[end]==0){
List asList = Arrays.asList(num[i],num[start],num[end]);
result.add(new ArrayList(asList));
start++;end--;
while(start
while(start
}else if(num[i]+num[start]+num[end]>0){
end--;
while(start
}else{
start++;
while(start
}
}
} return result;
}
}
weileyigenvhaishuati
发表于 2018-09-09 15:59:42
回复(0)
1
class Solution {
public:
vector > threeSum(vector &num) {
vector> res;
int sz=num.size();
if(sz<3)
return res;
unordered_multimap> co2;
unordered_multimap co1;
for(int i=0;i
{
co1.insert(make_pair(num[i],i));
for(int j=i+1;j
co2.insert(make_pair(num[i]+num[j],pair(i,j)));
}
for(auto i=co2.begin();i!=co2.end();i++)
{
int tp=(-1)*(i->first);
auto range=co1.equal_range(tp);
for(auto j=range.first;j!=range.second;j++)
{
int a=i->second.first;
int b=i->second.second;
int c=j->second;
if(a!=c&&b!=c)
{
vector temp={num[a],num[b],num[c]};
sort(temp.begin(),temp.end());
res.push_back(temp);
}
}
}
sort(res.begin(),res.end());
res.erase(unique(res.begin(),res.end()),res.end());
return res;
}
};
发表于 2018-06-04 11:00:39
回复(0)
1
vector > threeSum(vector &num) {
sort(num.begin(),num.end());
vector> res;
vector tmp;
int n=num.size();
for(int i=0;i<=n-3;i++){
int j=i+1;
int k=n-1;
if(i!=0&&num[i]==num[i-1])
continue;
while(i
if(num[j]+num[k]+num[i]<0)
j++;
else if(num[j]+num[k]+num[i]>0)
k--;
//(num[j]+num[k]==-num[i])
else{
tmp.push_back(num[i]);
tmp.push_back(num[j]);
tmp.push_back(num[k]);
res.push_back(tmp);
tmp.clear();
while(j
while(j
j++;
k--;
}
}
}
return res;
发表于 2017-11-05 21:17:59
回复(0)
1
class Solution {
public:
vector > threeSum(vector &num) { int len = num.size(); vector > result; sort(num.begin(), num.end()); for(int i=0;i0) r--; if(l v(3); v[0] = num[i]; v[1] = num[l]; v[2] = num[r]; result.push_back(v); while(l
}
};
发表于 2017-10-03 01:38:27
回复(0)
1
class Solution {
public:
vector > threeSum(vector &num) {
vector > ans;
sort(num.begin(),num.end());
for(int i=0;i+2
int l=i+1,r=num.size()-1;
while(l
while(l0) r--;
if(l==r) break; //注意判断下相等的时候break。
if(num[i]+num[l]+num[r]==0){
ans.push_back(vector{num[i],num[l],num[r]});
while(l
}
l++;
}
while(i+1
}
return ans;
}
};
发表于 2017-08-06 10:10:16
回复(0)
1
先排序,然后左右夹逼
class Solution {
public:
vector
> threeSum(vector &num) {
vector > result;
if(num.size()
< 3) return result;
sort(num.begin(),num.end());
const int target = 0;
auto last = num.end();
for(auto i=num.begin(); i
auto j = i + 1;
if(i > num.begin()
&& *i == *(i-1)) continue;
auto k = last -
1;
while(j < k){
if(*i + *j +
*k < target){
j++;
while(*j ==*(j-1) && j < k) j++;
}else
if(*i + *j + *k > target){
k--;
while(*k == *(k+1) && j < k) k--;
}else{
result.push_back({*i ,
*j, *k});
j++;
k--;
while(*j == *(j-1) && *k ==
*(k+1) && j
}
}
}
return result;
}
};
发表于 2016-06-28 09:05:09
回复(0)
0
vector > threeSum(vector &num) {
sort(num.begin(), num.end());
vector> res;
for(int i=0; i
{
if(num[i]>0) return res; //如果第一个数已经大于0,接下来都不必计算了,直接返回结果
if(i>0 && num[i]==num[i-1]) //第一次去重
continue;
int left = i+1;
int right = num.size()-1;
while(left
{
if(num[i]+num[left]+num[right]<0)
left++;
else if(num[i]+num[left]+num[right]>0)
right--;
else
{
res.push_back(vector{num[i],num[left],num[right]});
while(right>left && num[right]==num[right-1]) //第二次去重
right--;
while(right>left && num[left]==num[left+1]) //第三次去重
left++;
right--;
left++;
}
}
}
return res;
}
发表于 2021-05-18 18:01:52
回复(0)