组合总和

组合总和

CategoryDifficultyLikesDislikes
algorithmsMedium (72.75%)1922-

Tags

array | backtracking

Companies

snapchat | uber

给你一个  无重复元素  的整数数组  candidates  和一个目标整数  target ,找出  candidates  中可以使数字和为目标数  target  的  所有 不同组合 ,并以列表形式返回。你可以按  任意顺序  返回这些组合。

candidates  中的  同一个  数字可以  无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为  target  的不同组合数少于  150  个。

示例  1:

1
2
3
4
5
6
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例  2:

1
2
输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

1
2
输入: candidates = [2], target = 1
输出: []

提示:

  • 1 <= candidates.length <= 30
  • 1 <= candidates[i] <= 200
  • candidate  中的每个元素都  互不相同
  • 1 <= target <= 500

Discussion | Solution

解法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
struct Solution;

// @lc code=start
impl Solution {
    /// ## 解题思路
    /// - 迭代法
    /// 1. 将数组排序;
    /// 2. 依次从candidates中取出一个数,如果该数小于当前target,则加入临时数组中;
    pub fn combination_sum(candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
        ///
        fn combine_sum(candidates: &[i32], left: i32, sub: &[i32], res: &mut Vec<Vec<i32>>) {
            match left {
                n if n < 0 => return,
                0 => {
                    res.push(sub.to_vec());
                    return;
                }
                _ => {
                    candidates
                        .iter()
                        .filter(|&c| *c <= left)
                        .enumerate()
                        .for_each(|(i, c)| {
                            let mut s = sub.to_vec();
                            s.push(*c);
                            combine_sum(&candidates[i..], left - c, &s, res);
                        });
                }
            }
        }

        let mut res: Vec<Vec<i32>> = vec![];
        let mut c = candidates.to_vec();
        c.sort();
        combine_sum(&c, target, &vec![], &mut res);
        res
    }
}
// @lc code=end

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test() {
        assert_eq!(
            Solution::combination_sum(vec![2, 3, 6, 7], 7),
            vec![vec![2, 2, 3], vec![7],]
        );
        assert_eq!(
            Solution::combination_sum(vec![2, 3, 5], 8),
            vec![vec![2, 2, 2, 2], vec![2, 3, 3], vec![3, 5]]
        );
    }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
    vector<vector<int>> result;
public:
    /*
    * ## 解题思路
    * * 深度优先搜索
    */
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> tmp;
        dfs(candidates, tmp, target, 0);
        return result;
    }

    void dfs(vector<int>& candidates, vector<int>& tmp, int target, int s) {
        if (target < 0) {
            return;
        }
        if (target==0) {
            result.push_back(tmp);
        }
        for (int i=s; i<candidates.size(); i++) {
            // 当前元素大于剩余target, 剪支
            if (candidates[i]>target) {
                continue;
            }
            //
            tmp.push_back(candidates[i]);
            dfs(candidates, tmp, target-candidates[i], i);
            tmp.pop_back();
        }
    }
};
updatedupdated2024-08-252024-08-25