news 2026/10/28 10:47:35

算法日记:穷举vs暴搜vs深搜vs回溯vs剪枝--全排列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法日记:穷举vs暴搜vs深搜vs回溯vs剪枝--全排列

🎬 胖咕噜的稞达鸭:个人主页

🔥 个人专栏: 《数据结构》《C++初阶高阶》
《Linux系统学习》
《算法日记》
⛺️技术的杠杆,撬动整个世界!

全排列:

全排列

算法原理:

穷举–枚举

两数之和->两层 for 循环

  1. 画出决策树:

  2. 设计代码
    用一个全局变量:int[][]ret;来记录最终的结果;int[] path;对决策树进行深度优先遍历的时候记录一下路径;bool[]check;判断这条路径中此时这个位置的数字是否被使用过了,没有用过就添加进path,用check来实现剪枝。
    dfs函数:仅需关心某一个节点在干什么事情。
    细节问题:
    回溯:向上走的时候,干掉path的最后一个元素;修改check数组。
    剪枝:
    递归出口:遇到叶子节点的时候直接添加结果。

  3. 代码直译:

classSolution{vector<vector<int>>ret;//返回最后的结果vector<int>path;//记录路径boolcheck[7];//标记这个位置是否使用过,数组的下标public:vector<vector<int>>permute(vector<int>&nums){dfs(nums);//深度优先遍历returnret;}voiddfs(vector<int>&nums){if(nums.size()==path.size())// 终止条件:当前路径长度等于数组长度 → 找到一个完整排列{ret.push_back(path);//插入到ret返回数组中return;}for(inti=0;i<nums.size();i++){if(check[i]==false)//数字还没有用过,check数组表示元素有没有被使用过{path.push_back(nums[i]);//没有使用过插入到数组中check[i]=true;//标记为插入过了dfs(nums);//回溯--->恢复现场path.pop_back();//弹出check[i]=false;//标记为没插入,等下一轮}}}};

全排列二:

全排列II

这道题比上一道题多了一个剪枝的操作。

  1. 同一个节点的所有分支中,相同的元素只能选择一次。
  2. 同一个数只能使用一次—>check
  3. 只关心“不合法”的分支:
check[i]==true||((i!=0)&&nums[i]==nums[i -1]&&check[i]==fasle);

第一种不合法的情况:

(check[i]==true)i这个数字在之前已经使用过了

第二种不合法的情况:

(nums[i]==nums[i-1])而且 第二个同样的数字又出现了(check[i]==fasle;),

这个数字还不能是数组第一个元素(i != 0)处理[1,1,2,1],[1,2,1,3,1]这种数组,第二个1已经出现过了,第一次要剔除两个1留下[1,2]进行广度遍历。所以首先要把数组进行排序。
不合法的条件:

元素已经进去过的;
当前元素等于上一个元素,而且还是 进去过的(也就是说不可以重复进入)

  1. 还要只关心“合法”的分支(什么时候才进入dfs中)``
check[i]==false&&(i=0||nums[i]!=nums[i -1]||check[i -1]==true):

就是说合法可以进入路径的元素符合以下条件:

元素没进去过的;
当前元素跟上一个元素不同的;
虽然跟上一个数字相同但是目前元素没进去过的

  1. 代码直译:
classSolution{vector<vector<int>>ret;vector<int>path;boolcheck[9];public:vector<vector<int>>permuteUnique(vector<int>&nums){sort(nums.begin(),nums.end());//先排序dfs(nums,0);//从0的位置开始选择returnret;}voiddfs(vector<int>&nums,intpos){if(pos==nums.size()){ret.push_back(path);return;}for(inti=0;i<nums.size();i++){//剪枝//如果位置不合法,我们就直接跳过:已经进去过的;当前元素和上一个相同的 而且 上一个元素也进去过的if(check[i]==true||(i!=0&&nums[i]==nums[i-1]&&check[i-1]==false))continue;//位置合法就进去:还没进去过的; 当前元素和上一个元素相同但是上一个元素进去过此时的元素没进去过 ;当前元素不等于上一个元素的//(check[i] == false && check[i - 1] == true || nums[i] != nums[i-1] || i = 0)path.push_back(nums[i]);check[i]=true;dfs(nums,pos+1);path.pop_back();//恢复check[i]=false;}}};
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 15:51:13

直接法 读书笔记 00 目录

前言目录1 引言 1.1 线性代数 1.2 图论、算法与数据结构 1.3 延伸阅读2 基础算法 2.1 稀疏矩阵数据结构 2.2 矩阵‑向量乘法 2.3 工具函数 2.4 三元组形式 2.5 转置 2.6 合并重复项 2.7 删除矩阵中的项 2.8 矩阵乘法 2.9 矩阵加法 2.10 向量置换 2.11 矩阵置换 2.12 矩阵范数 2…

作者头像 李华
网站建设 2026/10/27 10:20:47

开发手机app防盗功能

我已经说完了------主要是针对静止手机被别人拿走的那种类型。比如放在桌子上的手机&#xff0c;不经意被人拿走。这个时候会报警。

作者头像 李华
网站建设 2026/10/27 19:43:54

乐天Rakuten开店:乐天Rakuten跨境店VS本土店?2026实战攻略

乐天Rakuten作为日本最大的电商平台之一&#xff0c;为全球卖家提供了广阔的商机。然而&#xff0c;如何选择合适的入驻方式、如何运营并获取高流量&#xff0c;仍然是许多卖家面临的难题。在这篇文章中&#xff0c;我们将全面解析如何根据自身情况选择本土店和跨境店的入驻方式…

作者头像 李华
网站建设 2026/10/23 12:28:14

如何选择一款真正能打通研发到生产的工业AI平台?

在制造业加速智能化转型的当下&#xff0c;企业对工业AI平台的需求早已不再停留在单点自动化或局部效率提升的层面。真正有远见的制造企业&#xff0c;正在寻找一种能够贯通研发、工艺、生产、质量乃至供应链的全链路智能中枢。然而&#xff0c;市面上的平台林林总总&#xff0…

作者头像 李华
网站建设 2026/10/20 9:39:29

基于深度学习YOLOv11的超市商品识别检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)

一、项目介绍 随着零售行业的快速发展&#xff0c;智能商品识别技术在超市自动化管理中扮演着重要角色。本文基于深度学习技术&#xff0c;提出了一种基于YOLOv11的超市商品识别检测系统。该系统通过YOLOv11算法实现了对295类超市商品的高精度实时检测&#xff0c;并集成了用户…

作者头像 李华
网站建设 2026/10/21 13:48:17

【计算机毕业设计案例】基于nodejs的计算机c语音自学交流平台基于nodejs+vue知识交流平台的实现与设计(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华