Combination Sum系列问题

主要使用方法是backtracking。

Combination Sum

Given a set of candidate numbers (C) 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.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • 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]

解答:为了减少许多不必要的循环过程,应该先把candidates排序,这样当目前遍历到的元素和已经大于target时,就可以不必再访问candidates后面的元素,直接退回到上个选择处进行选择。

另外,由于candidates集合中的每个数都可以使用无数次,故每次递归调用都应该从上次加入的元素开始遍历。

public class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new LinkedList<List<Integer>>();
        if (candidates == null || candidates.length == 0) {
            return result;
        }
        Arrays.sort(candidates);
        List<Integer> temp = new LinkedList<Integer>();
        helper(candidates, target, result, temp, 0);
        return result;
    }
    public void helper (int[] candidates, int target, List<List<Integer>> result, List<Integer> temp, int index) {
        if (target == 0) {
            result.add(new LinkedList<Integer>(temp));
            return;
        }
        for (int i = index; i < candidates.length && candidates[i] <= target; i++) {
            temp.add(candidates[i]);
            helper(candidates, target - candidates[i], result, temp, i);  //从上次加入的元素开始遍历
            temp.remove(temp.size() - 1);
        }
    }
}

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.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • 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, 7] 
[1, 2, 5] 
[2, 6] 
[1, 1, 6]

解答:与上题一样应该先把candidates排序。

这题需要注意的有两点是:

1. 每个元素只能用一次,所以每次递归都应该从当前加入元素的下一个元素开始遍历;

2. 集合中含有重复元素,所以在每次for循环在candidates挑选元素时,应将已经挑选过的元素过滤(因为加入此元素的结果已经加入结果集合),避免集合中结果出现重复。递归中则不用考虑起始点与上个元素是否相同,因为递归是在前面元素确定的情况下加入下一元素,它们在同一结果中。

public class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> rst = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
        helper(rst, temp, candidates, target, 0);
        return rst;
    }
    public void helper(List<List<Integer>> rst, List<Integer> temp, int[] candidates, int target, int index) {
        if (target == 0) {
            rst.add(new ArrayList<Integer>(temp));
            return;
        }
        for (int i = index; i < candidates.length && candidates[i] <= target; i++) {
            if (i > index && candidates[i] == candidates[i - 1]) {
                continue;
            }
            temp.add(candidates[i]);
            helper(rst, temp, candidates, target - candidates[i], i + 1);  //从下一个元素开始遍历
            temp.remove(temp.size() - 1);
        }
    }
}

Combination Sum III

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Ensure that numbers within the set are sorted in ascending order.

Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]

Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

解答:可以看做是上题的一种特殊情况, candidates数组中的元素为1到9,且不含重复元素,上题中去重的判断可以去掉。

public class Solution {
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> rst = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
        helper(rst, temp, k, n, 1);
        return rst;
    }
    public void helper(List<List<Integer>> rst, List<Integer> temp, int k, int n, int number) {
        if (k == temp.size() && n == 0) {
            rst.add(new ArrayList<Integer>(temp));
            return;
        }
        for (int i = number; i <= 9 && i <= n; i++) {
            temp.add(i);
            helper(rst, temp, k, n - i, i + 1);
            temp.remove(temp.size() - 1);
        }
    }
}

总结:本题需要注意的是每次递归里面的循环起始点,以及如何避免结果集的重复。

				
时间: 2024-08-29 06:13:02

Combination Sum系列问题的相关文章

leetcode笔记:Combination Sum III

一. 题目描述 Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Ensure that numbers within the set are sorted in ascending order. E

子集系列(二) 满足特定要求的子集,例 [LeetCode] Combination, Combination Sum I, II

引言 既上一篇 子集系列(一) 后,这里我们接着讨论带有附加条件的子集求解方法. 这类题目也是求子集,只不过不是返回所有的自己,而往往是要求返回满足一定要求的子集. 解这种类型的题目,其思路可以在上一篇文章的思路略作改进. 例 1,求元素数量为定值的所有子集 Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example,If n 

从Leetcode的Combination Sum系列谈起回溯法

在LeetCode上面有一组非常经典的题型--Combination Sum,从1到4.其实就是类似于给定一个数组和一个整数,然后求数组里面哪几个数的组合相加结果为给定的整数.在这个题型系列中,1.2.3都可以通过回溯法来解决,其实4也可以,不过由于递归地比较深,采用回溯法会出现TLE.因此本文只讨论前三题. 什么是回溯法?回溯法是一种选优搜索法,按选优条件向前搜索以达到目标.当探索到某一步时,发现原先的选择并不优或达不到目标,就退回异步重新选择.回溯法是深度优先搜索的一种,但回溯法在求解过程不

[LeetCode] Combination Sum III 组合之和之三

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Ensure that numbers within the set are sorted in ascending order. Example 1

【一天一道LeetCode】#40. Combination Sum II

一天一道LeetCode系列 (一)题目 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

leetcode笔记:Combination Sum II

一. 题目描述 Given a set of candidate numbers (C) 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 once number of times. Note: ? All numbers (including target)

【转载】Combination Sum

Combination Sum Given a set of candidate numbers (C) 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 (includi

【leetcode】Combination Sum

Combination Sum Given a set of candidate numbers (C) 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 (includi

[leetcode]Combination Sum @ Python

原题地址:https://oj.leetcode.com/problems/combination-sum/ 题意: Given a set of candidate numbers (C) 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