「代码随想录算法训练营」第二十二天 | 回溯算法 part4
491. 非递减子序列
题目链接:https://leetcode.cn/problems/non-decreasing-subsequences/
题目难度:中等
文章讲解:https://programmercarl.com/0491.递增子序列.html
视频讲解:https://www.bilibili.com/video/BV1EG4y1h78v/
题目状态:有思路,借助 ChatGPT 通过
思路:
在之前代码的基础上,添加一个set<vector<int>>
类型的全局变量,用来跟踪已添加的子序列,来避免重复子序列的存储。
代码:
class Solution { public: vector<vector<int>> res; vector<int> vec; set<vector<int>> seen; void backtracking(vector<int> &nums, int startIdx) { if(vec.size() >= 2) { if(seen.find(vec) == seen.end()) { res.push_back(vec); seen.insert(vec); } } for(int i = startIdx; i < nums.size(); ++i) { if(vec.empty() || nums[i] >= vec.back()) { vec.push_back(nums[i]); backtracking(nums, i + 1); vec.pop_back(); } } } vector<vector<int>> findSubsequences(vector<int>& nums) { backtracking(nums, 0); return res; } };
46. 全排列
题目链接:https://leetcode.cn/problems/permutations/
题目难度:中等
文章讲解:https://programmercarl.com/0046.全排列.html
视频讲解:https://www.bilibili.com/video/BV19v4y1S79W/
题目状态:有思路,借助 ChatGPT 通过
思路:
定义一个全局变量vector<bool> isUsed
,用来判断当前节点是否已经被回溯到了,若已经用过就直接跳过,之后使用回溯模板。
代码:
class Solution { public: vector<vector<int>> res; vector<int> vec; vector<bool> isUsed; void backtracking(vector<int> &nums) { if(vec.size() == nums.size()) { res.push_back(vec); return; } for(int i = 0; i < nums.size(); ++i) { if(isUsed[i]) continue; vec.push_back(nums[i]); isUsed[i] = true; backtracking(nums); vec.pop_back(); isUsed[i] = false; } } vector<vector<int>> permute(vector<int>& nums) { isUsed.resize(nums.size(), false); backtracking(nums); return res; } };
47. 全排列II
题目链接:https://leetcode.cn/problems/permutations-ii/
题目难度:中等
文章讲解:https://programmercarl.com/0047.全排列II.html
视频讲解:https://www.bilibili.com/video/BV1R84y1i7Tm/
题目状态:有思路,通过
思路:
将上面两题结合一下,分别创建一个vector<bool>
的全局变量来判断当前元素是否已经被使用,避免排列出来的单个结果中出现重复的元素;在定义一个set<vector<int>>
的全局变量,来判断所有排列中是否出现了重复的排列方案。
代码:
class Solution { public: vector<vector<int>> res; vector<int> vec; vector<bool> isUsed; set<vector<int>> seen; void backtracking(vector<int> &nums) { if(vec.size() == nums.size()) { if(seen.find(vec) == seen.end()) { res.push_back(vec); seen.insert(vec); } } for(int i = 0; i < nums.size(); ++i) { if(isUsed[i]) continue; vec.push_back(nums[i]); isUsed[i] = true; backtracking(nums); vec.pop_back(); isUsed[i] = false; } } vector<vector<int>> permuteUnique(vector<int>& nums) { isUsed.resize(nums.size(), false); backtracking(nums); return res; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?