leetcode 18. 4sum

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

思路:

之前的博客写过3sum的思想,其实这种算法就是要不断分解成2sum的问题。

首先遍历vector,然后将target-当前遍历元素的值作为3sum的target,然后进行输入到3sum的算法中输出结果,返回值与3sum不同的是,需要把当前遍历元素融入到vector当中。

使用set容器可以避免在元素中出现重复的元素。

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        set<vector<int>> result;
        sort(nums.begin(),nums.end());
        
        for(int i = 0; i < nums.size(); i++)
        {
            vector<vector<int>> temp = threeSum(nums, i,  target);
            //result.insert(result.begin(),temp.begin(),temp.end());
            for(int j = 0 ; j < temp.size(); j++)
                result.insert(temp.at(j));
        }
        vector<vector<int>> s;  
        insert_iterator<vector<vector<int>>> in_it(s, s.begin());  
        copy(result.begin(), result.end(), in_it);  
        return s;  
        //return result;
    }
    
    vector<vector<int>> threeSum(vector<int>& nums, int value_id, int target) {  
        set<vector<int>> result;  
        int value = nums.at(value_id);
        for(int i = 0; i < nums.size(); i++){  
            if(nums.size()<3)  
                break;  
            
            int c = value - target + nums.at(i);  
            int index_i = 0;  
            int index_j = nums.size()-1;  
            if(i == value_id)
                continue;
            if(index_i == value_id)
                index_i++;
            if(index_j == value_id && index_j>=1)
                index_j--;
            while(index_i < index_j){  
                if(index_i == i || index_i == value_id)  
                {  
                    index_i++;  
                    continue;  
                }  
                if(index_j == i || index_j == value_id)  
                {  
                    index_j--;  
                    continue;  
                }  
                if(nums.at(index_i) + nums.at(index_j) < -1*c)  
                    index_i++;  
                else if(nums.at(index_i) + nums.at(index_j) > -1*c)  
                    index_j--;  
                else  
                {  
                    if(index_i < i&& i < index_j)  
                    {  
                        vector<int> temp;  
                        temp.push_back(nums.at(index_i));  
                        temp.push_back(nums.at(i));  
                        temp.push_back(nums.at(index_j));  
                        result.insert(push_value_to_vector(temp,value));   
                    }else if(index_j < i){  
                        vector<int> temp;  
                        temp.push_back(nums.at(index_i));  
                        temp.push_back(nums.at(index_j));  
                        temp.push_back(nums.at(i));  
                        result.insert(push_value_to_vector(temp,value)); 
                    }else if(i < index_i){  
                        vector<int> temp;  
                        temp.push_back(nums.at(i));  
                        temp.push_back(nums.at(index_i));  
                        temp.push_back(nums.at(index_j));  
                        result.insert(push_value_to_vector(temp,value));  
                    }  
                    index_i++;  
                    index_j--;  
                }  
            }  
        }  
        vector<vector<int>> s;  
        insert_iterator<vector<vector<int>>> in_it(s, s.begin());  
        copy(result.begin(), result.end(), in_it);  
        return s;  
    }  
    
    vector<int> push_value_to_vector(vector<int>& source, int value){
        if(value < source.at(0))
            source.insert(source.begin(), value);
        else if(value < source.at(1))
            source.insert(source.begin() + 1, value);
        else if(value < source.at(2))
            source.insert(source.begin() + 2, value);
        else
            source.push_back(value);
        
        return source;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值