当前位置: 首页 > news >正文

第七章 回溯算法part04

2026.03.18 02.26 第三十天

491 非递减子序列

首先要是子序列,也就是说不能直接对原始数组排序,且要遍历全部节点,还得判断是不是非递减的。

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if(path.size() > 1) {result.push_back(path);}unordered_set<int> uset;for(int i = startIndex; i < nums.size(); i++) {if((!path.empty() && nums[i] < path.back())|| uset.find(nums[i]) != uset.end()) {continue;}uset.insert(nums[i]);path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}public:vector<vector<int>> findSubsequences(vector<int>& nums) {result.clear();path.clear();backtracking(nums, 0);return result;}
};

46 全排列

使用used数字记录元素是否已经使用过。

排列问题for循环要从0开始,且不需要使用startindex。

回溯:

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, vector<bool>& used) {if(path.size() == nums.size()) {result.push_back(path);return;}for(int i = 0; i < nums.size(); i++) {if(used[i] == true) continue;used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}public:vector<vector<int>> permute(vector<int>& nums) {result.clear();path.clear();vector<bool> used(nums.size(), false);backtracking(nums, used);return result;}
};

47 全排列||

怎么进行去重是关键。

最开始要进行排序,以便使用bool数组进行去重。

同一树枝可以使用值相同的元素,同一树层不行!

要理解怎样区分同一树枝已经使用和同一树层已经使用。

深度拆解:为什么 false 是树层,true 是树枝?
当我们遇到 nums[i] == nums[i-1] 时,我们需要决定是否跳过当前数字。

情况 A:used[i-1] == true(同一树枝)
场景:你正在填充 path 的第 2 位,而 path 的第 1 位已经放了 nums[i-1]。

状态:此时 used[i-1] 为 true,说明 nums[i-1] 在当前路径(树枝)上正在被使用。

逻辑:即使 nums[i] == nums[i-1],我们依然可以继续。比如数组 [1, 1, 2],我们在第一位选了第一个 1,第二位选第二个 1 是合法的,结果是 [1, 1, 2]。

情况 B:used[i-1] == false(同一树层)
场景:for 循环刚刚结束了对 nums[i-1] 的所有递归探索,回溯回来了。

状态:执行了 used[i-1] = false。现在循环到了 i,发现 nums[i] 和刚才处理完的 nums[i-1] 一模一样。

逻辑:如果你此时再选 nums[i] 开头,那么它后续能产生的所有排列,刚才 nums[i-1] 已经全部产生过了!

动作:为了去重,必须 continue。

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, vector<bool>& used) {if(path.size() == nums.size()) {result.push_back(path);return;}for(int i = 0; i < nums.size(); i++) {if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {continue;}if(used[i] == false) {used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}}public:vector<vector<int>> permuteUnique(vector<int>& nums) {result.clear();path.clear();sort(nums.begin(), nums.end());vector<bool> used(nums.size(), false);backtracking(nums, used);return result;}
};
http://www.jsqmd.com/news/495681/

相关文章:

  • VSCode 2026日志插件配置秘钥泄露(内部文档截图+7步零配置接入K8s日志流)
  • haihong Os 鸿蒙开源版开发一个pc版软件应用(1)
  • 北京朗格维修哪里好?六大城高端腕表故障排查+养护实用指南 - 时光修表匠
  • 上海徐汇区老房翻新装修公司哪家专业
  • ChatTTS部署进阶教程:Docker镜像自定义与API封装
  • 柔性振动盘与AI柔性摆盘机:重塑现代制造业的智能上料新范式
  • 服务器网卡设置一个静态IP,ipconfig之后出现两个IP,网络适配器中配置确实设置一个静态IP,现在怎么去掉下面那个,求解?
  • 获取的京东e卡在哪里可以回收兑换? - 抖抖收
  • 通义千问3-Reranker-0.6B效果实测:中英文混合文本排序案例分享
  • 手把手教你用XMind 2025打造高效学习系统:从康奈尔笔记到记忆曲线
  • 华为S5735交换机Telnet/SSH配置全攻略:从VLAN划分到用户认证一步到位
  • 剖析2026年余热锅炉控制系统供应商排名,睿控自动化优势凸显 - 工业设备
  • 欧洲航司二字码
  • 如何通过microG实现Android自由生态:终极解决方案完全指南
  • 说说全国循环流化床锅炉控制个性化定制,哪家品牌靠谱且性价比高 - 工业品牌热点
  • 电池充电放电控制的Matlab/Simulink仿真模型搭建
  • 2026六大城市高端腕表“价格迷局”终极档案:从北京百达翡丽1.5万洗油到南京欧米茄299元陷阱,你的保养费到底花在哪? - 时光修表匠
  • Alpha Shapes算法避坑指南:为什么你的点云轮廓提取总出错?
  • jemter之接口
  • 超表面(Metasurfaces)技术,将热释电探测器,提速到了皮秒级别
  • Fish-Speech-1.5镜像:基于Xinference部署,稳定高效的TTS服务
  • 【H5 前端开发笔记】第 02 期:HTML标签之间的关系、HTML注释、标签属性
  • 小白易懂!ESXi DCUI 登录审计全解(含实操脚本)
  • 手把手教你用Docker Compose离线部署OpenIM(含Nginx配置避坑指南)
  • 清洁度全自动检测设备性能评估:从样品前处理到数据分析 - 西恩士工业 - 工业设备研究社
  • 松材线虫病检测仪 松材线虫快速检测系统
  • 手机膜编码组合版(小红书改微信小店) 2026-3-18
  • 国产CRM系统哪个好?十大高性价比适合大中型企业的CRM排行 - SaaS软件-点评
  • 35岁程序员转行AI全攻略:岗位选择、学习路径及全景知识图谱,建议收藏!
  • Changedetection.io保姆级教程:用88邮箱实现国内SMTP通知+价格监控实战