一、题目描述
给定一堆数字,求出它们的全排列.
输入
{1,2,3}
输出
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]
二、思路
全排列问题是指给定一个字符串或者数组,求解字符串中字符或数组中数字所有可能出现的排列。我们在数学上碰到这种问题,第一反应肯定是先从1开始,找 [2,3] 的全排列;然后从2开始,找 [3] 的全排列;以此类推,显然最后变成了一个递归问题。
(1) 状态重置(交换)
import java.util.Arrays;
public class permutation {
private static void swap(int[] array,int start,int i){
int t = array[start];
array[start] = array[i];
array[i] = t;
}
public static void main(String[] args){
int[] array=new int[]{1,2,3};
permute(array, 0);
}
public static void permute(int[] array,int start){
if(start == array.length) {
System.out.println(Arrays.toString(array));
return;
}
for(int i = start; i < array.length; ++i) {
swap(array, start, i);
permute(array, start+1);
swap(array, start, i);
}
}
}
这里讲一下大概的逻辑:
-
首先数组 arr[1, 2, 3],第一次交换不会发生变化,因为 start == i
-
进入第一次 permute 递归 (start == 1),i == start == 1,也是没有交换,第二次递归,直到 start == 3之前都没有交换,到 start == 3,输出一次排列,第二次递归结束 (start == 2),退回第一次递归 (start == 1),进入第二次循环 (i == start == 1),然后第二遍循环 (i == 2),此时交换有作用 arr[1 , 3, 2].
-
… …
存在的问题:如果数组里面出现重复元素的话,那么 集合 一定会有重复的排列
如果想去掉重复元素那应该如何解决?我们最先想到的可能就是把存储结果的容器换成Set,因为Set的值是唯一的,这样可以保证没有重复的排列。最后,我们遍历Set即可