题目:

解答:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        int n=nums.size();
        vector<vector<int>> res;
        res.push_back(vector<int>());
        for(int i=0;i<n;i++){
            int currensize=res.size();
            for(int j=0;j<currensize;j++){
                res.emplace_back(res[j]);
                res.back().push_back(nums[i]);
            }
        }return res;
    }
};
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> path;
        int n = nums.size();
        // 枚举所有可能的组合大小(0到n)
        for (int k = 0; k <= n; k++) {
            generateCombinations(nums, 0, k, path, res);
        }
        return res;
    }
    void generateCombinations(vector<int>& nums, int start, int k,
                              vector<int>& path, vector<vector<int>>& res) {
        // 如果已经选了k个元素
        if (path.size() == k) {
            res.push_back(path);
            return;
        }    
        // 剪枝:如果剩余元素不够选了
        if (nums.size() - start < k - path.size()) {
            return;
        }   
        // 枚举选择
        for (int i = start; i < nums.size(); i++) {
            path.push_back(nums[i]);
            generateCombinations(nums, i + 1, k, path, res);
            path.pop_back();
        }
    }
};
心得:我原先想到的是递归的算法,即方法二,困难点是书写递归的部分以及跳入跳出。之所以需要push——back后再pop——back是因为最后失败情况需要调整回正常情况。
法一是更有特色,它是再前面的基础上新加入数字,需要极强的观察能力,我没有发现到....需要注意到的是
                res.emplace_back(res[j]);
                res.back().push_back(nums[i]);
第一行是添加一个res的一个容器,第二行是再最后一个容器基础上,对其内部数组进行添加。

题目:

解答:

class Solution {
public:
    void check(vector<vector<int>>& res, vector<int>& combine,
               vector<int>& candidates, int target, int start) {
        if(start==candidates.size())
            return;
        if (target == 0) {
            res.emplace_back(combine);
            return;
        }
        check(res,combine,candidates,target,start+1);
        if(target>=candidates[start]){
            combine.push_back(candidates[start]);
            check(res,combine,candidates,target-candidates[start],start);
            combine.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> combine;
        check(res, combine, candidates, target,0);
        return res;
    }
};
心得:发现回溯算法的常用思路就是递归,然后这类二维容器的题都是需要用到一维容器作为中间存储。这道题的关键在于直接进行后层递归,同时判定本层若重复是否还能作为解。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐