leetcode组合类问题的解析

leetcode组合类问题的解析

LC 39. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> ans;
        vector<int> path;
        backTrack(path, 0, target, ans, candidates);
        return ans;
    }

    void backTrack(vector<int>& path, int beginIndex, int target, vector<vector<int>>& ans, vector<int>& candidates){
        if(target==0){
            ans.push_back(path);
            return;
        }else if(target<0){
            return;
        }else{
            for(int i=beginIndex; i<candidates.size(); ++i){
                path.push_back(candidates[i]);
                backTrack(path, i, target-candidates[i], ans, candidates);
                path.pop_back();
            }
        }
    }
};

LC 40. 组合总和II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        std::sort(candidates.begin(), candidates.end());
        vector<vector<int>> ans;
        vector<int> path;
        backTrack(path, 0, target, ans, candidates);
        return ans;
    }

    void backTrack(vector<int>& path, int beginIndex, int target, vector<vector<int>>& ans, vector<int>& candidates){
        if(target==0){
            ans.push_back(path);
            return;
        }else if(target<0){
            return;
        }else{
            for(int i=beginIndex; i<candidates.size(); ++i){
                if(i>beginIndex && candidates[i]==candidates[i-1]){
                    continue;
                }
                path.push_back(candidates[i]);
                backTrack(path, i+1, target-candidates[i], ans, candidates);
                path.pop_back();
            }
        }
    }
};

LC 216. 组合总和III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。
解集不能包含重复的组合。
示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        int target = n;
        int pathLen = k;
        vector<int> candidates = {1,2,3,4,5,6,7,8,9};
        vector<vector<int>> ans;
        vector<int> path;
        backTrack(path, pathLen, 0, target, ans, candidates);
        return ans;
    }

    void backTrack(vector<int>& path, int pathLen, int beginIndex, int target, vector<vector<int>>& ans, vector<int>& candidates){
        if(target==0 && path.size()==pathLen){
            ans.push_back(path);
            return;
        }else if(target<0 || path.size()>=pathLen){
            return;
        }else{
            for(int i=beginIndex; i<candidates.size(); ++i){
                path.push_back(candidates[i]);
                backTrack(path, pathLen, i+1, target-candidates[i], ans, candidates);
                path.pop_back();
            }
        }
    }
};

LC 377. 组合总和IV

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例:

nums = [1, 2, 3]
target = 4

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

https://leetcode-cn.com/problems/combination-sum-iv/solution/dong-tai-gui-hua-python-dai-ma-by-liweiwei1419/

需要使用动态规划

dptable[i] += dptable[i-nums[j]];

class Solution {
public:
    long long combinationSum4(vector<int>& nums, int target) {
        vector<long long> dptable(target+1, 0);
        dptable[0] = 1;
        for(int i=1; i<=target; ++i){
            for(int j=0; j<nums.size(); ++j){
                if(nums[j]<=i){
                    if(dptable[i]>(INT_MAX-dptable[i-nums[j]])){
                        dptable[i] = INT_MAX;
                    }else{
                        dptable[i] += dptable[i-nums[j]];
                    }
                }
            }
        }
        return dptable[target];
    }
};

回溯法会超时。

class Solution {
public:
    int combinationSum4(vector<int>& candidates, int target) {
        //vector<vector<int>> ans;
        int ans = 0;
        vector<int> path;
        backTrack(path, target, ans, candidates);
        return ans;
    }

    void backTrack(vector<int>& path, int target, int& ans, vector<int>& candidates){
        if(target==0){
            //ans.push_back(path);
            ++ans;
            return;
        }else if(target<0){
            return;
        }else{
            for(int i=0; i<candidates.size(); ++i){
                path.push_back(candidates[i]);
                backTrack(path, target-candidates[i], ans, candidates);
                path.pop_back();
            }
        }
    }
};

LC 77. 组合

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        int pathLen = k;
        int candidates = n;
        vector<vector<int>> ans;
        vector<int> path;
        backTrack(path, pathLen, 1, ans, candidates);
        return ans;
    }

    void backTrack(vector<int>& path, int pathLen, int beginIndex, vector<vector<int>>& ans, int candidates){
        if(path.size()==pathLen){
            ans.push_back(path);
            return;
        }else if(path.size()>=pathLen){
            return;
        }else{
            for(int i=beginIndex; i<=candidates; ++i){
                path.push_back(i);
                backTrack(path, pathLen, i+1, ans, candidates);
                path.pop_back();
            }
        }
    }
};
发布了58 篇原创文章 · 获赞 11 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mhywoniu/article/details/105566003