LeetCode 遍历技巧 | 18. 4Sum

/*
 * Leetcode18. 4Sum
 * Funtion: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
            Find all unique quadruplets in the array which gives the sum of target.
 * Example:
    Input: given array S = [1, 0, -1, 0, -2, 2], and target = 0.
    Output: [
              [-1,  0, 0, 1],
              [-2, -1, 1, 2],
              [-2,  0, 0, 2]
            ]
    Input1:[-3,-2,-1,0,0,1,2,3]  0
    Expected1:[[-3,-2,2,3],[-3,-1,1,3],[-3,0,0,3],[-3,0,1,2],[-2,-1,0,3],[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
    Input2:[-1,2,2,-5,0,-1,4]   3
    Expected2:[[-5,2,2,4],[-1,0,2,2]]
 * Author: LKJ
 * Date:2016/7/29
 * Hint:related to 15.3Sum
        (穷举第一个和第二个元素,对第三个和第四个元素使用首尾逼近来枚举)
        具体思路和求3Sum的O(n2)方法相同,只是去重方法不同
        符合条件的元组已经找出了,下次哈希到相同的结果认为它们原来的元组相同(假设哈希未出现冲突),则跳过保存该结果。
        为了在求得符合条件的四元组后查找其哈希值时,提高查找速度,使用set或map来存储哈希值,其中的哈希值有序排列
        调用这两种容器自身的查找函数可以提高查找效率(内部一般使用二分查找法)。
        这里使用map和set在提交结果的时间上有所差别,应该二者内部实现还是有些差别,虽然可以将set也看做一种特殊map。
*/
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;



class Solution {
private:
    int myabs(int num){
        if(num < 0) num = -num;
        return num;
    }
public:
    vector< vector<int> > fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        int len = nums.size();
        int leftnum;
        int rightnum;
        int sum;
        vector<int> preAns;
        vector< vector<int> > ans;

        for(int i = 0; i < len-3; i++){
            if((i > 0) && (nums[i] == nums[i-1])) continue;//去重
            for(int j = i+1; j < len-2; j++){
                if((j > i+1) && (nums[j] == nums[j-1])) continue;//去重
                leftnum = j+1;
                rightnum = len-1;
                while(leftnum < rightnum){
                    if((leftnum > j+1) && (nums[leftnum] == nums[leftnum-1])) {leftnum++; continue;} //去重
                    sum = nums[i] + nums[j] + nums[leftnum] + nums[rightnum];
                    if(sum == target){
                        preAns.push_back(nums[i]);
                        preAns.push_back(nums[j]);
                        preAns.push_back(nums[leftnum]);
                        preAns.push_back(nums[rightnum]);

                        ans.push_back(preAns);
                        preAns.clear();
                    }
                    if(sum > target){
                        rightnum--;
                        if(nums[rightnum] == nums[rightnum+1]) rightnum--;//去重
                    }else{
                        leftnum++;
                        if(nums[leftnum] == nums[leftnum-1]) leftnum++;//去重
                    }
                }
            }
        }


        //也可以使用set去重
        /*
        set< vector<int> > ans;
        vector< vector<int> > newans;
        set<vector<int>>::iterator it = ans.begin();
        for(; it != ans.end(); it++)
            newans.push_back(*it);
        return newans;
        */
        return ans;
    }
};

int main(){
    int myarr[7] = {-1,2,2,-5,0,-1,4};
    vector<int> myin1(myarr,myarr+7);
    int myin;
    vector< vector<int> > myout;
    Solution SA;

    cout << "Please Enter" << endl;
    cin >> myin;
    myout = SA.fourSum(myin1,myin);

    cout<<"VecOUT:"<<myout.size()<<endl;
    for(unsigned int i = 0; i < myout.size(); i++){
        for(vector<int>::iterator itt = myout[i].begin() ;itt!=myout[i].end(); itt++){
            cout<<*itt<<"     ";
        }
        cout<<endl;
    }
    cout<<endl;

    cout<<endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值