zoukankan      html  css  js  c++  java
  • LeetCode(18)4Sum

    题目

    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.

    Note:
    Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)
    

    分析

    类似于15题求解的3Sum问题,这次求解4Sum问题,本质是相同的,不可以采用穷举法;
    其实求解4Sum问题可以分解为求3Sum问题,对数列依次遍历i,我们只需得到在第i个数后面,找出所有和为targetnums[i]的三元组,同理求3Sum又可以退化为2Sum,进而退化为1Sum
    因此,采用递归的思想解决KSum问题 ,但是递归的性能总是不满意的 , 意料之中的TLE。

    转换思路,我们可以使用2-sum的变形,两层遍历首先确定前两个元素,在确定后两个元素时采用2-sum的方式解决;

    学习:关于2-sum 3-sum 和 4-sum 乃至于k-sum问题一个很好的总结。

    AC代码

    class Solution {
    public:
        /*4-sum算法,递归实现,TLE*/
        vector<vector<int>> fourSum1(vector<int>& nums, int target) {
            if (nums.empty())
                return vector<vector<int>>();
    
            sort(nums.begin(), nums.end());
    
            return k_Sum(nums, 0, 4, target);
        }
        /*k-sum算法*/
        vector<vector<int>> k_Sum(vector<int> &nums, int begPos, int count, int target)
        {
            if (nums.empty())
                return vector<vector<int>>();
            /*所输入序列为已排序*/
            int len = nums.size();
            unordered_set<int> visited;
            vector<vector<int>> ret;
            vector<int> tmp;
            /*2-sum 处理*/
            if (2 == count)
            {
                int i = begPos, j = len - 1;
                while (i < j)
                {
                    int sum = nums[i] + nums[j];
                    if (sum == target && visited.find(nums[i]) == visited.end())
                    {
                        tmp.clear();
                        tmp.push_back(nums[i]);
                        tmp.push_back(nums[j]);
                        ret.push_back(tmp);
    
                        /*加入已访问set*/
                        visited.insert(nums[i]);
                        visited.insert(nums[j]);
    
                        ++i;
                        --j;
                    }//if
                    else if (sum < target)
                        ++i;
                    else
                        --j;
                }//while
            }//if
            else{
                for (int i = begPos; i < len; ++i)
                {
                    if (visited.find(nums[i]) == visited.end())
                    {
                        visited.insert(nums[i]);
                        /*得到k-1 sum的序列*/
                        vector<vector<int>> subRet = k_Sum(nums, i+1, count - 1, target-nums[i]);
                        if (!subRet.empty())
                        {
                            int sz = subRet.size();
                            for (int j = 0; j < sz; ++j)
                            {
                                subRet[j].insert(subRet[j].begin(), nums[i]);
                            }//for
                            ret.insert(ret.end(), subRet.begin(), subRet.end());
                        }//if
                    }//if
                }//for
            }//else
            /*返回结果集*/
            return ret;
        }
    
        /*4-sum算法,方法二,2-sum的变形*/
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            if (nums.empty() || nums.size() < 4)
                return vector<vector<int>>();
    
            sort(nums.begin(), nums.end());
            int len = nums.size();
            set<vector<int>> tmpRet;
            vector<vector<int>> res;
    
            for (int i = 0; i < len; ++i)
            {
                for (int j = i + 1; j < len; ++j)
                {
                    int beg = j + 1, end = len - 1;
                    while (beg < end)
                    {
                        int sum = nums[i] + nums[j] + nums[beg] + nums[end];
                        if (sum == target)
                        {
                            vector<int> tmp = { nums[i], nums[j], nums[beg], nums[end] };
                            tmpRet.insert(tmp);
    
                            ++beg;
                            --end;
                        }
                        else if (sum < target)
                        {
                            ++beg;
                        }
                        else
                            --end;
                    }//while
                }//for          
            }//for
            auto iter = tmpRet.begin();
            while (iter != tmpRet.end())
            {
                res.push_back(*iter);
                ++iter;
            }//while
            return res;
        }
    
    };

    GitHub测试程序源码

  • 相关阅读:
    MQTT
    群晖搭建webssh
    OSI 协议
    centos7 yum安装ffmpeg,以及ffmpeg的简单用法
    centos7 RTMP直播服务器搭建
    elasticsearch
    H5的storage
    bootstrap 列表組
    eclipse的debug模式下启动不了tomcat
    bootstrap collapse
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214922.html
Copyright © 2011-2022 走看看