2026.1.26力扣刷题笔记
·
题目:

解答:
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;
}
};
心得:发现回溯算法的常用思路就是递归,然后这类二维容器的题都是需要用到一维容器作为中间存储。这道题的关键在于直接进行后层递归,同时判定本层若重复是否还能作为解。
更多推荐



所有评论(0)