算法Day4-4个数之和

题目

给定n个整数的一个数组S,S中是否有元素a,b,c,d满足 a+b+c+d = 0 ? 找出数组中所有满足加和为target的不同的三个数组合。
注意:(a,b,c)中的元素必须是非降序的排列方式(即a<=b<=c)
解决方案中给出的集合不能包含重复的三元组
例如,给定的数组S={1 0 -1 0 -2 2},并且target = 0。
解决方案集合是
{-1, 0, 0, 1}
{-2, -1, 1, 2}
{-2, 0, 0, 2}

解析

本题其实是第一题“两数之和”的拓展,可以先获得(a+b)和(c+d)的所有可能集合S-Com,那么在S-Com上再做一遍“两数之和”,问题就解决了。 最后再将求得解的集合根据(a+b)和(c+d)与S中的映射关系还原回来即可。
下面代码并没有给出S-com与S的反映射。(ps.觉得有点繁琐,不是当前算法的重点。。。)

代码

#include<iostream>
#include<vector>
#include <algorithm>

using namespace std;

vector< vector<int> > twoSum(vector<int>&num, int target){
    sort(num.begin(), num.end());
    int start =0, end = num.size()-1;
    vector< vector<int> >  result;
    while(start < end){
        int sum = num[start] + num[end];
        if(sum == target){
            vector<int> solution;
            solution.push_back(num[start]);
            solution.push_back(num[end]);
            result.push_back(solution);
            start++; end--;
            //双指针扫描的去重
            while(start<end && num[start] == num[start-1])
                start++;//如果下一个元素与上一个元素相等,那么跳过
            while(start<end && num[end] == num[end+1])
                end--;//如果上一个元素和当前end相等,跳过这个
        }
        else if(sum < target)
            start++;
        else
            end--;
    }//end while

    //下面是输出
    vector< vector<int> >::iterator iter1;
    for(iter1 = result.begin(); iter1 != result.end(); iter1++){
        vector<int> vTemp = *iter1;
        vector<int>::iterator iter2;
        for(iter2 = vTemp.begin(); iter2 != vTemp.end(); iter2++){
            cout<<*iter2<<" ";
        }
        cout<<endl;
    }
    return result;

}

void main(){
    //numbers = {1 0 -1 0 -2 2}, target = 0
    int nums[] = {1,0,-1,0,-2,2};           //在这里改变数组值
    vector<int> v;
    for(int i=0; i<6; i++){
        for(int j=0; j<6; j++){
            if(i != j){
                v.push_back(nums[i] + nums[j]);
            }
        }
    }

    twoSum( v , 0);    //调用函数,结束
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值