K Sum 问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjxxyz123/article/details/79953890

相关问题总结

K Sum ?

    //从nums数组中选择能加出 target的 k 个数字,将所有不重复的可能性返回。
    public List<List<Integer>> kSum(int[] nums, int k, int target) {
        if (k < 2 || k > nums.length) {
            return new ArrayList<>();
        }
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        kSum(nums, k, target, 0, res, new ArrayList<Integer>());
        return res;
    }

    //从nums[begin...nums.length - 1]中任选k个数字,看能否加出target,将枚举出的可能性分别追加在path后面,然后将每一条路径添加进res
    public void kSum(int[] nums, int k, int target, int begin, List<List<Integer>> res, List<Integer> path) {
         //简单判断一下
        int max = nums[nums.length - 1];
        if (nums[begin] * k > target || max * k < target) {
            return;
        }
        if (k == 2) { // 当 k==2时,退化成 Two Sum, 相当于递归的 base case.
            int left = begin;
            int right = nums.length - 1;
            while (left < right) {
                if (nums[left] + nums[right] == target) {
                    List<Integer> newPath = new ArrayList<>(path);
                    newPath.addAll(Arrays.asList(nums[left++], nums[right--]));
                    res.add(newPath);
                    while (left < right && nums[left] == nums[left - 1]) {
                        ++left;
                    }
                    while (left < right && nums[right] == nums[right + 1]) {
                        --right;
                    }
                }else if (nums[left] + nums[right] > target) {
                    --right;
                }else {
                    ++left;
                }
            }
            return;
        }

        //枚举所有可能,然后进行dfs
        for (int i = begin; i + k - 1 < nums.length; i++) {
            if (i != begin && nums[i] == nums[i - 1]) {
                continue;
            }
            // 以下都是为了剪枝,但是呢,实际运行时间还是由用例决定的,因为判断还时耗时的,很难说好或者不好
            /*
            if (nums[i] + (k - 1) * max < target) {
                continue;
            }
            if (nums[i] * k > target) {
                break;
            }

            if (nums[i] * k == target && nums[i + k - 1] == nums[i]) {
                ArrayList<Integer> newPath = new ArrayList<>(path);
                for (int j = 0; j < k; j++) {
                    newPath.add(nums[i]);
                }
                res.add(newPath);
                return;
            }
            */
            path.add(nums[i]);
            kSum(nums, k - 1, target - nums[i], i + 1, res, path);
            //回溯!!!
            path.remove(path.size() - 1);
        }
    }
阅读更多

没有更多推荐了,返回首页