【LeetCode】4sum k-Sum 题解报告及总结

来源:互联网 发布:vb中borderstyle属性 编辑:程序博客网 时间:2024/06/08 16:31

【题目】
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: 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]
]

【解析】
根据前面的3sum的解题思路,可以将4sum的问题变成3sum的问题,即先确定第一个值,获得新的target,然后在根据3sum的解法求解。其实,3sum的问题并不是最终的求解单元,它也是先确定一个值,然后转化成2sum的问题再去求解。
由此看来,4sum的问题是在3sum的基础上加了一维,即时间效率为O(n^3).依次类推,k-sum的问题最终也可以转化成2sum的问题,最终的时间复杂度为O(n^(k-1)).为了解法通用,写成了递归的形式,代码如下:

    //4 sum的所有结果    public static List<List<Integer>> fourSum(int[] nums, int target) {        Set<List<Integer>> res = new HashSet<List<Integer>>();        if(nums == null || nums.length < 4)            return new ArrayList<List<Integer>>(res);        Arrays.sort(nums);        List<Integer> curres = new ArrayList<Integer>();        dfs(nums, target, res, curres, 0, 4);        return new ArrayList<List<Integer>>(res);    }    //k sum的所有结果    public static void dfs(int[] nums, int target, Set<List<Integer>> res, List<Integer> curres, int pos, int k){        //当仅省两个值的时候,计算并保存结果        if(curres.size() == k-2){            List<List<Integer>> tmp = twoSum(nums, target, pos, nums.length-1);            for(int i=0;i<tmp.size();i++){                List<Integer> tmpcur = new ArrayList<Integer>(curres);                tmpcur.addAll(tmp.get(i));                res.add(tmpcur);            }        }else{            for(int i=pos;i<nums.length;i++){                curres.add(nums[i]);                dfs(nums, target-nums[i], res, curres, i+1, k);                curres.remove(curres.size()-1);            }        }    }    //2sum的所有结果    public static List<List<Integer>> twoSum(int[] nums, int target, int l, int r){        List<List<Integer>> res = new ArrayList<List<Integer>>();        while(l<r){            int sum = nums[l]+nums[r];            if(sum == target){                List<Integer> tmp = new ArrayList<Integer>();                tmp.add(nums[l]);                tmp.add(nums[r]);                res.add(tmp);                l++;                r--;                continue;            }            if(sum < target){                l++;            }else{                r--;            }        }        return res;    }

递归的实现并不能保证4sum问题时间最优,只不过这里为了实现k-sum的解法。
leetcode上代码提交花费的时间:114 ms

0 0