• 40. 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, 7],
      [1, 2, 5],
      [2, 6],
      [1, 1, 6]
    ]

    分析

    这里和39类似,都是使用DFS。
    唯一需要注意的是:[1,1,2,5,6,7,10] 中,找到8
    如果使用39类似的方法,会出现两个[1,7]。 因为有两个重复的1。
    解决方法:
    在每一次调用helper函数的时候(代表同一层遍历)如果遇到c[i] == c[i - 1],比如已经把 index = 0 的1所有的可能DFS过了,那么再遇到 index = 1 的 1时候,就跳过,不进行DFS,因为之前的结果一定包含这次的结果。

    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
    class Solution {
    public:
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            vector<vector<int>> results;
            sort(candidates.begin(), candidates.end());
            helper(results, vector<int>{}, candidates, target, 0);
            return results;
        }
     
        void helper(vector<vector<int>> &results, vector<int> result, vector<int>& c, int target, int index) {
            for (int i = index; i < c.size(); ++i) {
                int t = target - c[i];
                if (t < 0) {
                    return;
                }
                else if(i==index || c[i] != c[i - 1]){ // jump over duplicate results
                    result.push_back(c[i]);
                    if (t == 0) {
                        results.push_back(result);
                    }
                    else {
                        helper(results, result, c, t, i + 1);// i + 1: insure every element is used once
                    }
                    result.pop_back();
                }
            }
        }
    };

    精简版
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class Solution {
    public:
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            vector<vector<int>> results;
            sort(candidates.begin(), candidates.end());
            helper(results, vector<int>{}, candidates, target, 0);
            return results;
        }
     
        void helper(vector<vector<int>> &results, vector<int> result, vector<int>& c, int target, int index) {
            if( target == 0){
                results.push_back(result);
                return;
            }
            for (int i = index; i < c.size() && target >= c[i]; ++i) {
                if(i==index || c[i] != c[i - 1]){ // jump over duplicate results
                    result.push_back(c[i]);
                    helper(results, result, c, target - c[i], i + 1);// i + 1: insure every element is used once
                    result.pop_back();
                }
            }
        }
    };





  • 相关阅读:
    C#继承之构造函数
    .Net Framework: 字符串的驻留(String Interning)
    解码 XML 和 DTD
    Java的静态变量初始化的坑
    创建执行jar包脚本
    jasypt 加密
    测试@Transactional
    linux如何查看端口被哪个进程占用
    径向基函数工作原理(样条函数)
    反距离权重插值的工作原理
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/079f1208560c9124fe6ad19b4017ed20.html
Copyright © 2020-2023  润新知