数组中相加和为0的三元组c语言,数组中相加和为0的三元组

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
矩阵相加算法: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int row; int col; int val; } Triple; void matrix_add(Triple a[], int a_len, Triple b[], int b_len, Triple c[], int *c_len) { if (a_len == 0 && b_len == 0) { *c_len = 0; return; } if (a_len == 0) { *c_len = b_len; for (int i = 0; i < b_len; i++) { c[i] = b[i]; } return; } if (b_len == 0) { *c_len = a_len; for (int i = 0; i < a_len; i++) { c[i] = a[i]; } return; } if (a[0].row > b[0].row || (a[0].row == b[0].row && a[0].col > b[0].col)) { matrix_add(b, b_len, a, a_len, c, c_len); return; } int i = 0, j = 0, k = 0; while (i < a_len && j < b_len) { if (a[i].row < b[j].row || (a[i].row == b[j].row && a[i].col < b[j].col)) { c[k++] = a[i++]; } else if (a[i].row > b[j].row || (a[i].row == b[j].row && a[i].col > b[j].col)) { c[k++] = b[j++]; } else { int val = a[i].val + b[j].val; if (val != 0) { c[k].row = a[i].row; c[k].col = a[i].col; c[k].val = val; k++; } i++; j++; } } while (i < a_len) { c[k++] = a[i++]; } while (j < b_len) { c[k++] = b[j++]; } *c_len = k; } int main() { Triple a[3] = {{0, 0, 1}, {1, 1, 2}, {2, 2, 3}}; int a_len = 3; Triple b[3] = {{0, 0, 1}, {1, 1, 2}, {2, 2, 3}}; int b_len = 3; Triple c[6]; int c_len; matrix_add(a, a_len, b, b_len, c, &c_len); for (int i = 0; i < c_len; i++) { printf("(%d, %d, %d)\n", c[i].row, c[i].col, c[i].val); } return 0; } ``` 矩阵转置算法: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int row; int col; int val; } Triple; void matrix_transpose(Triple a[], int a_len, Triple b[], int *b_len, int m, int n) { if (a_len == 0) { *b_len = 0; return; } int num[m], cpot[m]; for (int i = 0; i < m; i++) { num[i] = 0; } for (int i = 0; i < a_len; i++) { num[a[i].col]++; } cpot[0] = 0; for (int i = 1; i < m; i++) { cpot[i] = cpot[i - 1] + num[i - 1]; } for (int i = 0; i < a_len; i++) { int j = cpot[a[i].col]++; b[j].row = a[i].col; b[j].col = a[i].row; b[j].val = a[i].val; } *b_len = a_len; } int main() { Triple a[3] = {{0, 0, 1}, {1, 1, 2}, {2, 2, 3}}; int a_len = 3; Triple b[3]; int b_len; matrix_transpose(a, a_len, b, &b_len, 3, 3); for (int i = 0; i < b_len; i++) { printf("(%d, %d, %d)\n", b[i].row, b[i].col, b[i].val); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值