一、全排列初识
从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n 个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。
二、问题引入
看了上面的定义还是一脸糊涂?不要紧,先看看下面的例子,你就会对全排列概念有个具体的认识:
对于一个给定的序列 a = [a1, a2, a3, … , an],请设计一个算法,用于输出这个序列的全部排列方式。
例如:a = [1, 2, 3]
输出
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]
这就是一个简单的全排列问题,单纯看上面的例子,貌似看起来很简单,用眼盯着可能都能算对,但是如果数组a的值个数增加到十个百个呢,那手算出来的概率就变得很低很低了,这时候就要利用算法来解决这一类问题。
三、递归实现
我们先考虑两种情况,
1. 数组元素互不相同
如果数组a中所有元素都不相同,每个数值都是唯一的,这时候问题就简单了,只需要进行dfs算法深度优先搜索,就可以实现,看代码:
import java.util.Arrays;
public class 全排列 {
public static void main(String[] args) {
int[] a = {
1, 2, 3};//无重复元素
allrange(a, 0, a.length - 1);
}
//全排列(递归回溯)
private static void allrange(int[] a, int cursor, int end) {
// 递归终止条件
// 已经到序列结尾了
if (cursor == end) {
System.out.println(Arrays.toString(a));
}
//初始 i=游标,因为 游标 之前的顺序已经确定了,不需要再排列了
for (int i = cursor; i <= end; i++) {
swap(a, cursor, i);//固定游标,让 i 值不断变化,去输出当前后面的各种顺序的排列
allrange(a, cursor + 1, end);
swap(a, cursor, i);// 回到交换之前的序列,这里可以理解为回溯,保证下一个值不受上一个值的影响(记忆抹去)
}
}
private static void swap(int[] a, int cursor, int i) {
int temp = a[cursor

本文深入讲解全排列的概念,包括无重复元素与有重复元素数组的递归实现,并通过实例分析,如带分数表示法问题,巩固全排列算法的理解。
&spm=1001.2101.3001.5002&articleId=108228785&d=1&t=3&u=dc17b94d83a44d7bb0c04e968a74796c)
8768

被折叠的 条评论
为什么被折叠?



