蓝桥杯 算法 全排列讲解 附模板 让小学生来都看得懂,看不懂你上门砍我

全排列的概念

全排列是什么?

直接上百度的定义

全排列的本质

讲人话:从一个数组中抽取确定量数量的元素,组成一个新的数组。并根据题中的问题,对新组成的数组进行条件
判断。是否满足条件,如果满足条件,就做出一定的代码行为。
伪代码如下
全排列函数体(){
数组 [] list =现有确定;
	if(满足条件( list )){
		执行目标函数;
		return ; 这里必须要加,不加是给自己debug添堵
	}
}
满足条件(数组[] list){
	条件判断函数;
}

以上是对某一单一排列做出的条件判断,而我们的目标是对一个数组,[] list,做出条件判断。那么问题就来了,如果枚举出所有的情况呢?

生成一个数组的所有排列

您看到这篇文章的时候应该已经做过一些题了,可能会感觉到非常困惑,为啥咱就是看不懂他们写的代码?
例如有些大佬,交换一下数组中的元素就形成了排列。有些大佬对元素位置判断一下就形成了排列。

原理讲解

从一个数组中取出N个元素,形成一个新的数组。我们实际是按照N位元素,在N的每一位上,不重复的添加元素,并继
续向下一位添加。(这里描述有点问题,自己动脑子想一想,兄弟语文不好)

举例说明:从[1,2,3]中,抽取两个2元素,组成全排列。当第一位取1的时候,后面的第二位便无法取1,只能取2或
3

看到这里,你肯定已经明白了全排列用代码实现的原理(每一位,在当前位可取的范围进行枚举,然后转移到下一位)
如果当前位枚举了一个元素,则后面位不可使用。
伪代码:
[] 当前可选取的情况;
for(int i :当前可选取的情况){
	
	当前位置 =i;0
	//因为当前位置选取了i,所以要把i从当前可选取的情况中去除掉,以免后面的元素选取
	当前可选取的情况 扣除i;
	进行下一层的枚举(K+1);  //确定了第K位,我们现在需要枚举第K+1位
	//当前 层 的所有子情况已经讨论完毕,既 ABC ----的情况已经讨论完毕,排列将进入ABD----的情况
	//i不会在这一层被选取了,所以要恢复i
	当前可选取的情况增加i;
	
}

另一种方式

从当前层开始for循环,交换数组元素。 原理是利用这样子交换当前层通样不会重复,自己去想。
这个其实和上面的方法大同小异,只是代码写起来少个两三排。因为这个方法没有保证全排列的有序性(出现顺序),
自己想一下[1,2,3]的全排列使用这个方法是什么样子的。

模板

递归出口什么的多自己想想,懒得写了,网课杀我
import java.util.*;

public class 蓝桥排列 {
	static char[] list = "LANQIAO".toCharArray();
	static boolean[] vis = new boolean[7];//判断在当前状况下,哪一位已经被取了
	static char[] put = new char[7]; //存放每一位的情况
	public static HashSet<String> set = new HashSet<String>();//用于最终的条件判断

	public static void main(String[] args) {
		dfs(0);
		for(String i:set) {System.out.println(i);}
		System.out.println(set.size());
	}
	//不知道dfs是什么的朋友自己百度,这个简单
	public static void dfs(int pos) {
		if(pos==7) {//已经枚举了所有位(7位),进行条件判断。并中止
			set.add(new String(put));
			return ;
		}
		for(int i=0;i<vis.length;i++) {
			if(!vis[i]) {
				vis[i]=true;
				put[pos]=list[i];
				dfs(pos+1);
				vis[i]=false;
			}
		}
	}
}
原创文章 12 获赞 25 访问量 395

猜你喜欢

转载自blog.csdn.net/qq_42499133/article/details/105673146