【算法】【回溯】两道经典排列问题OJ详解【力扣46 力扣47】【超详细的回溯算法教程】让我们牢牢把握回溯的精髓
【算法】【回溯】两道经典排列问题OJ详解【力扣46 力扣47】【超详细的回溯算法教程】让我们牢牢把握回溯的精髓
作者: @小小Programmer
这是我的主页:@小小Programmer
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
力扣刷题专栏:Leetcode想要冲击ACM、蓝桥杯或者大学生程序设计竞赛的伙伴,这里面都是博主的刷题记录,希望对你们有帮助!
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力。看完之后别忘记关注我哦!️️️
本篇建议收藏后食用~
题目:
OJ46:46. 全排列
OJ47:47. 全排列 II
OJ46 全排列
题目描述

实现思路
首先,这两道题我们肯定是要用回溯实现的,我们要通过回溯,来找到每一种排列方式。
因此,在这里,博主先带着大家复习一下回溯算法的精髓
回溯算法的三部曲:
- 确定递归函数参数和返回值
- 确定递归终止条件
- 确定单层递归逻辑
一:确定递归函数的参数和返回值
这里和组合问题是不一样的,因为排列问题是有顺序可言的,比如例题一:我们要找[1,2,3]的排列,第二次从2开始找的时候,前面的1也是要进去的,即[1,2..]和[2,1...]是不同的排列,因此,我们的递归函数除了原来的数组之外,还需要一个数组来记录,哪一个数字已经用过了。 比如第一个数字挑了2,即[2,...],此时,第二个数字的选择只能是1或者3,因为2已经用过了。
所以我们的递归函数:
void backtracking(vector<int>& nums, vector<bool>& used)
当然,我们还需要创建全局的两个数组,一个用来做最后结果的收集,一个用于递归回溯。
vector<vector<int>>ret;
vector<int>path;
二:确定递归终止条件
很明显,当递归数组(path)满了的时候,就终止递归。
比如:求[1,2,3]的排列,当一个数组path[]收集到3个数的时候,就要返回了,比如path里面是[2,1,3]的时候,如果只有两个或者一个数,递归就要继续。
if (path.size() == nums.size()) {
ret.push_back(path);
return;
}
三. 确定单层递归逻辑
当然,单层搜索就是递归了
- 递归回溯永不分离
- 一次递归伴随着一次回溯
所以我们每次递归完一定要记得撤销,回溯。
完整代码
//OJ46 全排列
class Solution {
private:
vector<vector<int>>ret;
vector<int>path;
void backtracking(vector<int>& nums, vector<bool>& used) {
//此时说明找到了一组结果
//2.终止条件
if (path.size() == nums.size()) {
ret.push_back(path);
return;
}
//3.单层搜索
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) {
vector<bool>used(nums.size(), false);
backtracking(nums, used);
return ret;
}
};
/*
* 和组合问题的区别
* 每层都是从0开始搜索,而不是从startIndex开始搜索---[1,2]中用过1了,但是[2,1]中还得用1
* 需要used数组记录path中都存放了哪些元素
*/
//used是用来防止同一个数选两次的
OJ47 全排列ll
题目描述

实现思路
这其实就是一个经典的去重问题,方法同样是用used数组来完成去重
要注意的点:
- 去重之前要对数组进行排序,要将一样的数字放在一起
- 去重的判断条件,当当前下标所对应的数和前一个下标所对应的数一致,并且这个数并不是在同一个树枝上时去重
一:确定递归函数的返回值和参数
void backtracking(vector<int>& nums, vector<bool>& used)
二:确定递归的终止条件,这些都和前面一样的。
if (path.size() == nums.size()) {
ret.push_back(path);
return;
}
三:确定单层搜索逻辑:
- 具体的去重实现,请看完整代码的注释,若还有不明白的,可以私信博主噢! 其实这个去重思路是非常经典的思路,是必须要掌握的!
完整代码
class Solution {
private:
vector<vector<int>>ret;
vector<int>path;
void backtracking(vector<int>& nums, vector<bool>& used) {
if (path.size() == nums.size()) {
ret.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;//首先一定要i>0,保证这不是这棵树的根节点
//nums[i]==nums[i-1]说明可能会出现重复,但是此时不确定是这两个相同的数出现在同一树层上还是同一树枝上
//如果实在同一树枝上,是可以的,比如在[1,1,2]是没问题的
//但是如果是在同一树层上是不行的,可能会出现重复
//所以used[i-1]=false 保证这是在同一树层上的,而不是同一树枝上的
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) {
sort(nums.begin(), nums.end());
vector<bool>used(nums.size(), false);
backtracking(nums, used);
return ret;
}
};
//为什么去重的时候写第二个&&左边写
//used[i-1]==false;或used[i-1]=true;都可以呢?
//因为在树枝上去重和在树层上去重都可以的
//在树层上去重的效率很高,
//在树枝上去也可以,但是做了很多无用的搜索
尾声
看到这里相信你对排列问题的这两道OJ已经有一定的理解了,其实排列问题是一个非常经典的我们必须要掌握的问题。
在走之前,可以再看看博主的这些专栏内容对你是否有帮助: 有的话请不要吝啬你们的点赞收藏关注和转发噢!
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
力扣刷题专栏:Leetcode想要冲击ACM、蓝桥杯或者大学生程序设计竞赛的伙伴,这里面都是博主的刷题记录,希望对你们有帮助!
【算法】【回溯】两道经典排列问题OJ详解【力扣46 力扣47】【超详细的回溯算法教程】让我们牢牢把握回溯的精髓的更多相关文章
- 【转载】NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩、机器学习及最优化算法
原文:NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩.机器学习及最优化算法 导读 AI领域顶会NeurIPS正在加拿大蒙特利尔举办.本文针对实验室关注的几个研究热点,模型压缩.自 ...
- PHP用strtotime()函数比较两个时间的大小实例详解
在PHP开发中,我们经常会对两个时间的大小进行判断,但是,在PHP中,两个时间是不可以直接进行比较,因为时间是由年.月.日.时.分.秒组成的,所以,如果需要将两个时间进行比较的话,我们首先要做的就是将 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- 【转】小波与小波包、小波包分解与信号重构、小波包能量特征提取 暨 小波包分解后实现按频率大小分布重新排列(Matlab 程序详解)
转:https://blog.csdn.net/cqfdcw/article/details/84995904 小波与小波包.小波包分解与信号重构.小波包能量特征提取 (Matlab 程序详解) ...
- openerp经典收藏 字段定义详解(转载)
字段定义详解 原文地址:http://shine-it.net/index.php/topic,2159.0.htmlhttp://blog.sina.com.cn/s/blog_57ded94e01 ...
- openerp经典收藏 对象定义详解(转载)
对象定义详解 原文地址:http://shine-it.net/index.php/topic,2159.0.htmlhttp://blog.sina.com.cn/s/blog_57ded94e01 ...
- 一个经典的 HTTP协议详解
1引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1 ...
- 二分算法题目训练(三)——Anton and Making Potions详解
codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...
- [转]从两道经典试题谈C/C++中联合体(union)的使用
宋宝华 21cnbao sweek@21cn.com 试题一:编写一段程序判断系统中的CPU是Little endian还是Big endian模式? 分析: 作为一个计算机相关专业的人,我们应该在计 ...
- 看到两道小学数学题,实在是解不动,用js写了一下
把一个自然数的约数(除去它本身)按照从小到大的顺序写在它的左边,可以得到一个多位数,比如6的约数是1,2,3,写成一个多位数是1236,假如这个多位数中,没有直复数字,那么我们你这个多位数是唯一的.请 ...
随机推荐
- Codeforce:Good Bye 2020 个人题解
题面链接:Here 代码提交:Here 年终彩蛋 1466A. Bovine Dilemma 题意是:给定一个固定点(0,1),然后给定n个在x轴的点,求面积不同的三角形个数 简单思考一下就容易发现这 ...
- 应届生必读:Java真实项目的开发流程和常用工具
本文出自本人写的书,谢绝转载,更勿抄袭. 本人有多年的Java面试官经验,经常要和一些包装项目经验的求职者打交道.当然平时也兼职做些Java面试辅导工作,最近也陆续帮一些在校生朋友成功找到Java工作 ...
- 在wsl2 kali发行版中安装docker
前言 因为不想开虚拟机,而又需要多个linux发行版来做测试,也不想使用docker-desktop来曲线救国,所以想直接安装个docker随时使用,这一路也是踩了不少坑.直接复制进终端进行安装 su ...
- Fedora 设置 core 文件路径
sudo vim /etc/sysctl.conf 输入 kernel.core_pattern=core.%p sudo /lib/systemd/systemd-sysctl 使修改生效 cat ...
- 基于java+springboot的求职招聘网站-求职招聘管理系统
该系统是基于java+springboot开发的求职招聘网站.网上招聘管理系统.网上人才招聘系统.毕业生求职招聘系统.大学生求职招聘系统.校园招聘系统.企业招聘系统.是给师弟开发的毕业设计.大家学习过 ...
- 一个WPF开发的打印对话框-PrintDialogX
今天五月一号,大家玩的开心哦. 1. 介绍 今天介绍一个WPF开发的打印对话框开源项目-PrintDialogX,该开源项目由<WPF开源项目:AIStudio.Wpf.AClient>作 ...
- CSS - 滤镜的妙用 - 制作炫彩圆环(外加动画)
效果图如下: 话不多说,上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- Grub2 内核启动参数总结
Grub2 内核启动参数总结 部分参数 biosdevname=0 net.ifnames=0 # 注意这个配置会修改网卡的名字, 比如之前是ens192 # 添加如上两个内容后就会变成 eth0 类 ...
- [转帖]TIDB-Error 1105: Out Of Memory Quota问题解决
一.背景 复杂sql查询报错 二.原因 单条s q l使用内存默认为1G 三.解决 tiup cluster edit_config tidb-test server_configs: tidb: m ...
- iftop的学习与使用
iftop的学习与使用 背景 前段时间一直进行netperf 等网络性能验证工具的学习与使用. 监控很多时候采用了 node-exporter + prometheus + grafana来进行观察 ...