「代码随想录算法训练营」第二十天 | 回溯算法 part2
1.「代码随想录算法训练营」第二天 | 数组 part22.「代码随想录算法训练营」第三天 | 链表 part13.「代码随想录算法训练营」第四天 | 链表 part24.「代码随想录算法训练营」第一天(补) | 数组 part15.「代码随想录算法训练营」第五天 | 哈希表 part16.「代码随想录算法训练营」第六天 | 哈希表 part27.「代码随想录算法训练营」第七天 | 字符串 part18.「代码随想录算法训练营」第八天 | 字符串 part29.「代码随想录算法训练营」第九天 | 栈与队列 part110.「代码随想录算法训练营」第十天 | 栈与队列 part211.「代码随想录算法训练营」第十一天 | 二叉树 part112.「代码随想录算法训练营」第十二天 | 二叉树 part213.「代码随想录算法训练营」第十三天 | 二叉树 part314.「代码随想录算法训练营」第十四天 | 二叉树 part415.「代码随想录算法训练营」第十五天 | 二叉树 part516.「代码随想录算法训练营」第十六天 | 二叉树 part617.「代码随想录算法训练营」第十七天 | 二叉树 part718.「代码随想录算法训练营」第十八天 | 二叉树 part819.「代码随想录算法训练营」第十九天 | 回溯算法 part1
20.「代码随想录算法训练营」第二十天 | 回溯算法 part2
21.「代码随想录算法训练营」第二十一天 | 回溯算法 part322.「代码随想录算法训练营」第二十二天 | 回溯算法 part423.「代码随想录算法训练营」第二十三天 | 贪心算法 part124.「代码随想录算法训练营」第二十四天 | 贪心算法 part225.「代码随想录算法训练营」第二十五天 | 贪心算法 part326.「代码随想录算法训练营」第二十六天 | 贪心算法 part427.「代码随想录算法训练营」第二十七天 | 贪心算法 part528.「代码随想录算法训练营」第二十八天 | 动态规划 part129.「代码随想录算法训练营」第二十九天 | 动态规划 part230.「代码随想录算法训练营」第三十天 | 动态规划 part331.「代码随想录算法训练营」第三十一天 | 动态规划 part432.「代码随想录算法训练营」第三十二天 | 动态规划 part533.「代码随想录算法训练营」第三十三天 | 动态规划 part634.「代码随想录算法训练营」第三十四天 | 动态规划 part735.「代码随想录算法训练营」第三十五天 | 动态规划 part836.「代码随想录算法训练营」第三十六天 | 动态规划 part937.「代码随想录算法训练营」第三十七天 | 动态规划 part1038.「代码随想录算法训练营」第三十八天 | 动态规划 part1139.「代码随想录算法训练营」第三十九天 | 动态规划 part1240.「代码随想录算法训练营」第四十一天 | 单调栈 part141.「代码随想录算法训练营」第四十天 | 动态规划 part1342.「代码随想录算法训练营」第四十二天 | 单调栈 part243.「代码随想录算法训练营」第四十三天 | 图论 part144.「代码随想录算法训练营」第四十四天 | 图论 part245.「代码随想录算法训练营」第四十五天 | 图论 part346.「代码随想录算法训练营」第四十六天 | 图论 part447.「代码随想录算法训练营」第四十七天 | 图论 part548.「代码随想录算法训练营」第四十八天 | 图论 part649.「代码随想录算法训练营」第四十九天 | 图论 part750.「代码随想录算法训练营」第五十天 | 图论 part851.「代码随想录算法训练营」第五十一天 | 图论 part952.「代码随想录算法训练营」第五十二天 | 图论 part1053.「代码随想录算法训练营」完结!39. 组合总和
题目链接:https://leetcode.cn/problems/combination-sum/
题目难度:中等
文章讲解:https://programmercarl.com/0039.组合总和.html
视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ
题目状态:久违的通过!
思路:
使用回溯模板,在单层循环时判断当前数组值是否大于目标值,若大于,直接跳过,其他思路就是和回溯模板中一样,直接看代码。
代码:
class Solution { public: vector<vector<int>> res; vector<int> vec; void backtracking(vector<int> &candidates, int target, int startIndex) { if(target == 0) { res.push_back(vec); return; } for(int i = startIndex; i < candidates.size(); ++i) { if(candidates[i] > target) continue; vec.push_back(candidates[i]); target -= candidates[i]; backtracking(candidates, target, i); vec.pop_back(); target += candidates[i]; } } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { backtracking(candidates, target, 0); return res; } };
剪枝优化后的代码:
class Solution { private: vector<vector<int>> result; vector<int> path; void backtracking(vector<int>& candidates, int target, int sum, int startIndex) { if (sum == target) { result.push_back(path); return; } // 如果 sum + candidates[i] > target 就终止遍历 for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) { sum += candidates[i]; path.push_back(candidates[i]); backtracking(candidates, target, sum, i); sum -= candidates[i]; path.pop_back(); } } public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { result.clear(); path.clear(); sort(candidates.begin(), candidates.end()); // 需要排序 backtracking(candidates, target, 0, 0); return result; } };
40. 组合总和II
题目链接:https://leetcode.cn/problems/combination-sum-ii/
题目难度:中等
文章讲解:https://programmercarl.com/0040.组合总和II.html
视频讲解:https://www.bilibili.com/video/BV12V4y1V73A
题目状态:借助ChatGPT通过
思路:
在每层递归的时候,要确保当前递归的值和前一个递归的值不相等。因此需要首先对数组排序,之后在执行回溯三部曲。
代码:
class Solution { public: vector<vector<int>> res; vector<int> vec; void backtracking(vector<int> &candidates, int target, int startIdx) { if(target == 0) { res.push_back(vec); return; } for(int i = startIdx; i < candidates.size(); ++i) { if(i > startIdx && candidates[i] == candidates[i - 1]) continue; if(target < candidates[i]) break; target -= candidates[i]; vec.push_back(candidates[i]); backtracking(candidates, target, i + 1); target += candidates[i]; vec.pop_back(); } } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); backtracking(candidates, target, 0); return res; } };
131. 分割回文串
题目链接:https://leetcode.cn/problems/palindrome-partitioning/
题目难度:中等
文章讲解:https://programmercarl.com/0131.分割回文串.html
视频讲解:https://www.bilibili.com/video/BV1c54y1e7k6
题目状态:这题好难,看题解通过
思路:
通过回溯,每层分割是按照几个元素来分,每次分割后判断分割出来的元素是否是一个回文串,直接理解代码会更好理解一些。
代码:
class Solution { public: vector<vector<string>> res; vector<string> vec; bool isLoop(string s, int start, int end) { for(int i = start, j = end; i < j; i++, j--) if(s[i] != s[j]) return false; return true; } void backtracking(string s, int startIdx) { if(startIdx >= s.size()) { res.push_back(vec); return; } for(int i = startIdx; i < s.size(); ++i) { if(isLoop(s, startIdx, i)) { string str = s.substr(startIdx, i - startIdx + 1); vec.push_back(str); } else { continue; } backtracking(s, i + 1); vec.pop_back(); } } vector<vector<string>> partition(string s) { backtracking(s, 0); return res; } };
合集:
「代码随想录算法训练营」
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?