全排列问题的解题思路

news2024/11/17 4:49:05

假设有这么个正整数n,要求输出1到n的所有排列?

输入:3
输出:123,132,213,231,312,321

一、无脑循环求解?

拿到这个问题,当然我的第一个想法就是 for 循环,比如这样:

for(int i = 1; i < n+1; i++){
	for(int j = 1; j < n+1; j++){
		for(int k = 1; k < n+1; k++){
			……从此陷入无尽的循环
		}
	}
}

可是,问题大了,循环到底有多少个?n 个?

又或者是 while 循环来控制循环次数:

while(i < n){
	for(int j = 1; j < n+1; j++){
		……就这样又陷入循环
	}
	i++;
}

其实,如果了解回溯算法,也不至于拿个 for 循环来为难自己,下面就来分析一下这个问题。

二、全排列的个数

首先,关于这个全排列问题,很容易就能得到问题的答案个数为 n!个:

当 n = 2 时,全排列的个数为 2 个:

[1,2]、[2,1]

当 n = 3 时,全排列的个数为 3*2 ,即 6 个:

[1,2,3]、[1,3,2]、[2,1,3]、[2,3,1]、[3,1,2]、[3,2,1]

当 n = 4 时,全片列的个数为 4*3*2 ,即 24 个

[1, 2, 3, 4]、[1, 2, 4, 3]、[1, 3, 2, 4]、[1, 3, 4, 2]、[1, 4, 2, 3]、[1, 4, 3, 2]、
[2, 1, 3, 4]、[2, 1, 4, 3]、[2, 3, 1, 4]、[2, 3, 4, 1]、[2, 4, 1, 3]、[2, 4, 3, 1]、
[3, 1, 2, 4]、[3, 1, 4, 2]、[3, 2, 1, 4]、[3, 2, 4, 1]、[3, 4, 1, 2]、[3, 4, 2, 1]、
[4, 1, 2, 3]、[4, 1, 3, 2]、[4, 2, 1, 3]、[4, 2, 3, 1]、[4, 3, 1, 2]、[4, 3, 2, 1]

很容易推出 n 个数字时,全排列的个数为 n! 个。

三、回溯算法解题

接下来就利用回溯算法来解决这个问题,还是比较简单的。首先,我们需要构建全排列的解空间。同样这里先研究规模较小的问题,假设 n 为 3 时的解空间:

在这里插入图片描述
回溯算法的解空间就是一颗多叉树,通常根节点为空。这这颗多叉树中,叶子结点被称为不可扩展的结点,非叶子结点称为可扩展结点。

接下来,就需要通过深度遍历来遍历这颗多叉树,每次遍历至叶子结点,就可以得到一个相应的解。

在这里插入图片描述

回溯就发生在遍历的过程中,当遇到不可扩展的结点时,就需要回溯到树的上一层,继续遍历其他可扩展结点。

接下来就可以用代码来实现了,主要有两种方式来实现回溯算法:

1、递归实现回溯算法

  递归实现思路:函数自调,通过自调函数来不断向树的深处进行遍历;而通过 for 循环,来找到合适的结点,并暂存在结果集中。递归终止时,即获得一个完整的结果!

/**
 * 
 * @param t 	起始层数,初始值为 1
 * @param n		数的个数,也是树的最后一层
 * @param ls	结果集
 */
public static void backTrack(int t, int n, ArrayList<Integer> ls) {
		if(t > n) {
			System.out.println(ls.toString());
		}else {
			for(int i = 1; i < n+1; i++) {
				if(ls.contains(i))
					continue;
				else
					ls.add(i);
				backTrack(t+1, n, ls);
				ls.remove(t-1);
			}

		}
}

在这里插入图片描述

下面是递归调用的抽象过程:
在这里插入图片描述
观察这个过程,你会发现递归对于回溯算法是具有天生的优势的,或者说递归就是一个不断回溯的过程;而迭代实现回溯算法是比较难以理解的。

2、迭代实现回溯算法

  递归实现思路:使用迭代来实现回溯,就像一头扎进死胡同,然后再一步一步回退,回退之后再扎进死胡同。直到回退到胡同外,即退出整个回溯过程。

/**
 * @param n 	数的个数
 * @param ls	结果集
 */
public static void iterativeBacktrack(int n, ArrayList<Integer> ls) {
		int t = 1;
		int left = 1;
		while(t > 0) {
			if(left <= n) {
				for(int i = left; i <= n; i++) {
					if(ls.contains(i)) {
						continue;
					}else {
						if(ls.size() == t){
							ls.set(t-1, i);
						}else{
							ls.add(t-1, i);
						}
						i = 0;
					}
					if(t == n) {
						System.out.println(ls.toString());
					}else {
						t++;
						i=0;
					}
				}
			}
			if (t > 0){
				ls.remove(t-1);
			}
			t--;
			if(t > 0)
				left = ls.get(t-1);
		}
}

在这里插入图片描述


其实回溯算法还有最后一步,通过约束条件和边界控制来剪去多余的枝干,以提升回溯算法的效率。 这里,就不进行剪枝了……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上下文驱动的图上文案生成

✍&#x1f3fb; 本文作者&#xff1a;持信、弈臻、悟放、积流、孟诸1. 摘要为商品图片上特定位置配上装饰性文案来突出重点在广告业务中有着十分广泛的应用前景。然而&#xff0c;现有的图片文案描述生成系统均生成与图片位置关系无关的文案&#xff0c;无法很好地应用到广告业…

66. Python 类的总结

66. 类的总结 文章目录66. 类的总结1. 类2. 对象3. 类的语法4. 属性5. 方法6. 创建对象7. 调用属性8. 调用方法9. 方法的值的传递第1情况&#xff1a;没有值第2种情况&#xff1a;有值10. __init__方法1. __init__写法2. __init__作用3. 重点关注11. 自定义函数和方法的异同1. …

Unity渲染管线(Render Pipeline)笔记

Rendering是什么 渲染Rendering可以理解为将拿到的3D数据生成一副2D图像的过程。 这些3D数据包含&#xff1a;3D模型本身的点的信息&#xff0c;三角形面的描述信息&#xff0c;模型应用的材质以及摆放的虚拟相机的信息等。Rendering过程会使用全部的数据&#xff08;物体的几何…

摄像头录像大师推荐?如何录制摄像头,图文教程

现如今&#xff0c;很多笔记本电脑上都会携带摄像头&#xff0c;用来录制摄像头画面&#xff0c;方便小伙伴的时候。可很多小伙伴却表示&#xff0c;自己不知道电脑摄像头画面该如何录制。有什么有什么好用的摄像头录制大师&#xff1f;如何录制摄像头画面&#xff1f;本篇文章…

【10w字】超详细【百分百拿offer】的面试教程,接口测试篇

1.请问你是如何做接口测试的&#xff1f; 大体来说&#xff0c;经历以下过程&#xff1a;接口需求调研、接口测试工具选择、接口测试用例编写、接口测试执行、接口测试回归、接口测试自动化持续集成。 具体来说&#xff0c;接口测试流程分成以下九步&#xff1a; 第一步&…

RabbitMq之发布确认(高级)

一.发送消息到交换机失败 正常情况下生产者只发布消息到交换机&#xff0c;无法确定是否成功把消息发送到交换机当中&#xff0c;由此发布确认的回调函数可以通知生产者消息是否发送到了交换机。 代码如下 1.先创建交换机、队列等信息 package jot.jothot.testMq;import or…

OS 学习笔记(6) 操作系统引导

OS 学习笔记(6) 操作系统引导 这篇笔记对应的王道OS 1.5 操作系统引导&#xff0c;同时参考了 《Operating System Concepts, Ninth Edition》和 俗称ostep的《 Operating Systems: Three Easy Pieces》还有 《Operating Systems: Principles and Practice》 文章目录OS 学习笔…

实战还原--从大黄蜂样本到域控管理员技术解析

0 前言实战案例还原《BumbleBee Roasts Its Way To Domain Admin》一文详细的描述了一次渗透案例&#xff0c;但其文章组织架构建立在ATT&CK框架上&#xff0c;而不是按照时间线逻辑来组织&#xff0c;因此对于渗透人员了解学习其前后过程有些困难&#xff0c;特此梳理一番…

发布微信小程序获取收集用户信息权限

前言在发布微信小程序的时候我们经常会遇到审核不通过的情况&#xff0c;其中一种特别让我头疼就是说小程序收集、使用和储存用户信息。不给予通过。但是他们的接口又不能提供这个功能&#xff0c;并且老是改动&#xff0c;真的特别的麻烦加无语。有时候审核偷一下懒&#xff0…

算法刷题-回文数、找出小于平均值的数、旋转图像(C_C++)

文章目录回文数找出小于平均值的数旋转图像回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的…

光电耦合器和MOSFET之间的差异

光电耦合器和MOSFET之间的差异 介绍 光电耦合器/光耦合器和固态继电器&#xff08;光电MOSFET或光耦MOSFET&#xff08;OCMOS FET&#xff09;&#xff09;在保持电隔离的同时传输信号&#xff0c;但存在一些重要差异。 结构差异 下图显示了光电耦合器和OCMOS FET的主要内部…

Vue实战第2章:简单的分配页面布局

缓冲 前言 本篇在讲什么 本篇作为Vue实战的第二章&#xff0c;跟代码逻辑无关&#xff0c;主要是简单的先设计一下个人网站的各个模块内容&#xff0c;明确一下我们想要将网站做出什么样子 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上…

趣味三角——第6章——两个几何定理

第6章 两个几何定理 It is the glory of geometry that from so few principles, fetched from without, it is able to accomplish so much. (几何学的荣耀在于&#xff0c;仅从几个原理出发&#xff0c;外求于无物&#xff0c;但却能够完成如此非凡的壮举。) ——Isaac N…

linux基本功系列-top命令实战

文章目录一. top命令介绍二. 语法格式及常用选项三. 参考案例3.1 显示进程信息3.2 显示完整的进程命令3.3 以批处理的形式展示3.4 设置信息更新频次3.5 显示指定进程号的信息3.6 top面板中常用参数3.7 其他用法四. top的相关说明4.1 交互命令介绍4.2 top面板每行信息的含义4.2.…

MySQL(八):事务的隔离级别、MVCC的原理

目录一、事务的隔离级别1.1 事务的隔离性1.2 事务并发执行引发的一致性问题1.2.1 脏写1.2.2 脏读1.2.3 不可重复读1.2.4 幻读1.3 SQL标准中的四种隔离级别1.4 MySQL中支持的4中隔离级别二、MVCC原理2.1 版本链2.2 ReadView2.3 READ COMMITED 每次读取数据前都生成一个ReadView2…

使用独立显卡安装黑苹果,但无法扩展显示器的解决方案

使用独立显卡安装黑苹果&#xff0c;但无法扩展显示器的解决方案 网上的教程 本文的外部链接&#x1f517; 引用文中的一句话&#xff1a;“这也许是无法驱动独显的黑苹果笔记本想要外接显示器的唯一方案。” ---- 购买拥有displaylink的外置显卡的usb转接器 文章作者给我了…

word@菜单自定义和公式输入

菜单栏快捷键设置 word 设置(选项) Word options (General) - Microsoft Support 点击文件->选项 自定义word菜单 自定义功能区 Customize the ribbon in Word - Microsoft Support Customizing the source list of commandsThe ribbon listAdd or remove commandsReor…

[golang Web开发] 2.golang web开发:操作数据库,增删改查,单元测试

简介 Go 语言中的 database/sql包定义了对数据库的一系列操作,database/sql/driver包定义了应被数据库驱动实现的接口&#xff0c;这些接口会被sql包使用.但是 Go语言没有提供任何官方的数据库驱动&#xff0c;所以需要导入第三方的数据库驱动,不过连接数据库之后对数据库操作的…

超经典JavaIDEA 10个插件 Java开发工程师

工欲善其事&#xff0c;必先利其器。 作为一名合格的程序员&#xff0c;合理配置我们所用的IDEA&#xff0c;是高效开发的必修课。而如今的插件工具也越来越好用&#xff0c;不仅基本具备了智能提示&#xff0c;还可以自动补全代码&#xff0c;甚至能够在查出bug的同时提供修改…

如何彻底删除硬盘数据?电脑高手也恢复不了

实用的小命令,就是彻底删除硬盘上的数据,硬盘恢复软件也恢复不了! 1.以管理员身份运行cmd窗口,打开cmd,如下图所示: 2.在命令提示窗口中,直接输入cipher /w:路径,输入这个命令加上路径即可将文件彻底删除! 可以从整个命令说明上看到是从整个卷上可用的未使用磁盘空间…