40. 组合总和 II

发布时间 2023-08-01 21:47:21作者: lixycc

40. 组合总和 II

方法:回溯

解题思路

  • 如何去重?
  • 答:对相同的元素进行统一的处理,即枚举当前操作选几个该元素。

代码

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector<pair<int, int>> unique_seq;
        for (auto &num : candidates) {
            if (unique_seq.empty() || num != unique_seq.back().first) {
                unique_seq.emplace_back(num, 1);
            } else {
                unique_seq.back().second ++ ;
            }
        }
        int n = unique_seq.size();
        vector<vector<int>> ans;
        vector<int> cur;
        function<void(int, int)> dfs = [&](int pos, int sum) -> void {
            if (sum == target) ans.emplace_back(cur);
            if (pos == n || target - sum < unique_seq[pos].first) return ;
            dfs(pos + 1, sum);
            int num = unique_seq[pos].first, cnt = unique_seq[pos].second;
            int most = min((target - sum) / num, cnt);
            for (int i = 1; i <= most; i ++ ) { // 枚举
                cur.push_back(num);
                dfs(pos + 1, sum + i * num);
            }
            for (int i = 1; i <= most; i ++ ) {
                cur.pop_back();
            }
        };
        dfs(0, 0);
        return ans;
    }
};

复杂度分析

时间复杂度:\(O(2^n * n)\)
空间复杂度:\(O(n)\)