Leetcode Combinations问题总结

@author stormma
@date 2017/11/30


生命不息,奋斗不止!


题目1

Given two integers n and k, return all possible combinations of k numbers out of 1 … n

Example
n = 4, k = 2

            [2,4],
            [3,4],
            [2,3],
            [1,2],
            [1,3],
            [1,4]

题目意思很简单,就是从n个数(1-n)中取k个数的组合。简单的dfs+回溯即可。

代码实现

/**
     * <p>Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.</p>
     *
     * <em>Example 1</em>
     *
     * if n = 4 and k = 2
     *
     * <code>
     *       [2,4],
     *       [3,4],
     *       [2,3],
     *       [1,2],
     *       [1,3],
     *       [1,4]
     * </code>
     */
    static class Question1 {
        public List<List<Integer>> combine(int n, int k) {
            List<List<Integer>> ans = new ArrayList<>();
            dfs(k, n, 1, ans, new LinkedList<>());
            return ans;
        }

        /**
         * @param k 表示从start开始取k个数的组合
         * @param n 
         * @param start
         * @param ans
         * @param current 临时的结果
         */
        private void dfs(int k, int n, int start, List<List<Integer>> ans, List<Integer> current) {
            // 此次搜索完成
            if (k == 0) {
                ans.add(new ArrayList<>(current));
                return;
            }

            for (int i = start; i <= n; i++) {
                current.add(i);
                dfs(k - 1, n, i + 1, ans, current);
                ((LinkedList) current).pollLast();
            }
        }

        public static void main(String[] args) {
            System.out.println(new Question1().combine(4, 2));
        }
    }

题目2 Combination Sum

Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:

[
  [7],
  [2, 2, 3]
]

题目分析

与题目一类似,这次是在数组中找出和 = target的组合,我们仿照题目1的解法来dfs+回溯解决此问题。

代码实现

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> ans = new ArrayList<>();
        dfs(candidates, target, ans, new ArrayList<>(), 0);
        return ans;
    }

    private void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> current, int start) {
        if (target == 0) {
            ans.add(new ArrayList<>(current));
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            int num = candidates[i];
            if (num > target) return;

            current.add(num);
            dfs(candidates, target - num, ans, current, i);
            current.remove(current.size() - 1);
        }
    }
}

题目3 Combination Sum II

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,
A solution set is:

题目分析

这道题目有个限制,一个元素只能被使用一次,而且不能有重复,比如[1, 1, 7]和[1, 7, 1]就是重复的。那么说明如果数组为[1, 1, 7, 1], target = 9,那么我们的答案理应只有[1, 1, 7]不能包含其他重复的。此题对于Combination Sum那个题目来说,难点是去重。偷懒的做法是直接使用Set来进行去重。

方法二,我们先进行排序, 如:

[1, 1, 1, 7]

我们开始搜索,第一次搜索我们可以得到[1, 1, 7]这个答案,第二次搜索从index = 1,[index = 1] = 1 ==上次开始的[index = 0] = 1。所有,这种情况我们应该跳过。按照这个,我们很容易写出我们的代码

代码实现

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(candidates);
        dfs(candidates, target, 0, ans, new ArrayList<>());
        return ans;
    }

    private void dfs(int[] candidates, int target, int start, List<List<Integer>> ans, List<Integer> current) {
        if (target == 0) {
            ans.add(new ArrayList<>(current));
            return;
        }

        for (int i = start; i < candidates.length; i++) {
            int num = candidates[i];
            if (num > target) return;
            if (i > start && candidates[i] == candidates[i - 1]) continue;
            current.add(num);
            dfs(candidates, target - num, i + 1, ans, current);
            current.remove(current.size() - 1);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值