尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

代码随想录Day25_回溯5_全排列

代码随想录Day25_回溯5_全排列
📅 发布时间:2026/6/22 9:04:56
代码随想录Day25_回溯5_全排列

非递减子序列

问题描述

给了一个数组,要求给出其所有长度>=2的非递减子序列。

思路

压入结果的条件是path.size()>=2,回溯过程结束的条件是移动到了边上startIndex>=num.size()
在树中,非递减序列,要求压入的元素必须比之前压入的大:if(path.empty()||nums[i]>=path.back())

问题

如果给出的数组包含重复元素,那么答案的集合中就会包含重复的数组;
alt text
那我标记该位置的元素已经用过了,如何?````

    if(used[i]==false&&(path.empty()||nums[i]>=path.back())){path.push_back(nums[i]);used[i]=true;backtrack(nums,i+1,used);path.pop_back();used[i]=false;}

alt text
这样也是不行的,原因在于数组不同下标处的元素可能相等,这样只是标记了一个位置的该元素,但是如果该位置后面的元素和已经遍历过的元素有相同的,也会导致结果集中存在一样的数组。所以重点不是对下标记录,而是对这个元素本身的值进行记录。使用哈希容器unorder_set<int> usedThisLeval

        for(int i=startIndex;i<nums.size();i++){if(usedThisLeval.contains(nums[i])){continue;}if(path.empty()||nums[i]>=path.back()){path.push_back(nums[i]);usedThisLeval.insert(nums[i]);backtrack(nums,i+1);path.pop_back();}}

但是似乎很慢!

原始思路解法代码

class Solution {
public:vector<int>path;set<vector<int>>  res;void backtrack(vector<int>&nums, int startIndex){if(path.size()>=2){res.insert(path);}if(startIndex>=nums.size()){return;}for(int i=startIndex;i<nums.size();i++){if(path.empty()||nums[i]>=path.back()){path.push_back(nums[i]);backtrack(nums,i+1);path.pop_back();}}}vector<vector<int>> findSubsequences(vector<int>& nums) {path.clear();res.clear();backtrack(nums,0);return vector<vector<int>>(res.begin(),res.end());}
};

全排列

题目描述

给定一个不含重复数字的数组,返回其所有可能的全排列。
看到题目第一眼,感觉这道题和之前做过的组合问题很相似。组合问题:在n个数中找K个数的组合。复用后发现不同,N个数的组合在组合问题中是这种情况
alt text
在回溯的这颗树中,在移动startIndex的过程中之前的数就不会考虑进来了,但是排列问题需要考虑进来。
解决办法是vector & used标记状态

class Solution {
public:vector<int>path;vector<vector<int>>  res;void backtrack(vector<int>&nums, vector<bool>&used){if(path.size()==nums.size()){res.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]);backtrack(nums,used);path.pop_back();used[i]=false;}}}vector<vector<int>> permute(vector<int>& nums) {path.clear();res.clear();vector<bool>used(nums.size(),false);backtrack(nums,used);return res;   }
};

全排列2

问题理解

数组中出现了重复元素,使用暴力set去重,但是似乎是一种很慢的方法,相当于每次插入都要遍历一次所有组合。
alt text

代码

class Solution {
public:vector<int>path;vector<vector<int>>  res;void backtrack(vector<int>&nums, vector<bool>&used){if(path.size()==nums.size()){res.push_back(path);return;}for(int i=0;i<nums.size();i++){if(i>0&&nums[i]==nums[i-1]&&used[i-1]==true){continue;//跳出本次循环}if(used[i]==false){used[i]=true;path.push_back(nums[i]);backtrack(nums,used);path.pop_back();used[i]=false;}}}vector<vector<int>> permuteUnique(vector<int>& nums) {path.clear();res.clear();sort(nums.begin(),nums.end());vector<bool>used(nums.size(),false);backtrack(nums,used);return res; }
};

总结

在排列问题中使用startIndex来标记位置,因为排列是从后面每次都经过。但在组合问题中,答案集合是不关心位置的,固定元素的不同组合。首先对数组进行排序,使用used看是否用过。

相关新闻

  • 深入解析:MyBatis 源码深度解析:从 Spring Boot 实战到底层原理
  • 泣かないで、またおいで——NOIP2025游记,以及 OI 回忆录。
  • 深入解析:IHR 2025 | 移远通信携Robrain AI解决方案亮相,开启机器人全感官交互新纪元

最新新闻

  • 2026年最新通化市黄金回收白银回收铂金回收彩金回收靠谱门店TOP5权威榜单+实体老店联系方式 - 亦辰小黄鸭
  • 从Overleaf部署到密码安全:Docker环境下的bcrypt哈希与MongoDB实践
  • Terraform变量依赖与条件逻辑:构建可演进的基础设施程序
  • 2026年最新通辽市黄金回收白银回收铂金回收彩金回收靠谱门店TOP5权威榜单+实体老店联系方式 - 亦辰小黄鸭
  • 向后误差分析与eggshel工具:从Shel范畴论到系统稳定性验证实践
  • Java FileWriter生产级实战:编码、线程安全与资源管理

日新闻

  • 2026速览惠州叛逆青少年学校前十大排名名单出炉 - 武汉中职最新信息发布
  • 2026上饶白蚁消杀哪家好?15年本土2大权威白蚁防治公司推荐(金盾虫控/青蚁卫士) - 我叫一
  • 天龙八部单机版终极数据管理工具:5个技巧快速掌握游戏数据编辑

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号