leetcode-18 4Sum(kSum)

本题,与3Sum类似。
只需在3Sum的基础上再加一层循环即可。

总结规律,在网上查询,发现目前比较好的办法就是以最初的2Sum为基础,将kSum逐渐降低k值,直到最终弱化为2Sum。
即:kSum->(k-1)Sum->……->4Sum->3Sum->2Sum.

网上多是直接解决4Sum的解法,其算法思路固然很好,却丧失了程序的灵活性。
本人结合大家的思路,贡献一个采用递归的kSum的程序,可自由设定k值和target。通过leetcode。
优点:可灵活设定K值和target,解决一系列的类似问题
缺点:存储中间结果需要多次的push_back() 和pop_back(),所以速度有点慢,leetcode显示时间为185ms.

主要思路:
假设,K>=2。
采用递归的思想,逐步弱化:kSum->(k-1)Sum->……->4Sum->3Sum->2Sum.
确定递归的最终情况:2Sum。
鉴于leetcode的测试要求,定义一个暂时的vector v,用于存储每一种结果,期间根据需要进行push_back() 和pop_back()。

代码如下:

class Solution {
public:
//希望能够写成Ksum的程序,而不是只是针对4sum的。为此,需要写递归迭代的办法。
    void twoSum( vector<int> &num, int dex, vector<vector<int> > &result, vector<int> v, int target)
    {
        int i=dex;
        int j=num.size()-1;
       while(i < j)
       {
           if(num[i]+num[j] > target)
           --j;
           else if(num[i]+num[j] < target)
           ++i;
           else
           {
               //找到匹配的,则存入结果
               v.push_back(num[i]);
               v.push_back(num[j]);
               result.push_back(v);
               v.pop_back();//及时清除v中最后两个数据,继续向后方扫,寻找匹配值
               v.pop_back();
               i++;
               j--;
               //跳过2Sum中的重复值
               while(i < num.size() && num[i]==num[i - 1]) i++;    
               while(j >= 0 && num[j] == num[j + 1]) j--; 
           }
       }
    }
    void kSum( vector<int> &num, int dex, vector<vector<int> > &result,vector<int> v, int target, int k )
    { 
        if(k > 2)
        {
            for(int i=dex+1; i < num.size()-1; ++i)
            {
                v.push_back( num[i-1]);
                kSum(num, i, result, v, target-num[i-1], k-1);
                v.pop_back();//当前走完,需要跳到下一个i,需要先清除v中最近一个数据
                while( i > 0 && num[i] == num[i-1] )//跳过子(k)层的连续相同的数据,则跳过                         
                    ++i;
            }
        }
        else
        twoSum( num, dex, result, v, target);
    }
    vector<vector<int> > fourSum(vector<int> &num, int target) {
    /*
    由于leetcode的测试直接给了target,此处没有定义target,但是可以灵活修改target的值,
    */
        sort(num.begin(), num.end());//排序
        vector<vector<int> > result;//保存最终结果
        vector<int> curResult;//保存中间结果
        int count = 4;//K值 
        if(num.size() >= count)
        kSum(num, 0, result, curResult, target, count);
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值