1. 题目描述
2. 思路图解
- 往盒子里放卡片
- 判断是假想的盒子吗?
- 如果是,把前面四个盒子里的卡片的值一次输出
- 否则依次枚举手里的卡片,卡片值小的放在盒子里
再去下一个盒子放卡片
3. 代码实现
伪代码
//在当前盒子里放卡片
void permute(int cur)
{
//判断当前盒子是假想的盒子吗?
如果是,那么就依次输出前面所有盒子里卡片的值
否则
{
枚举手里的卡片,从小到大的顺序
{
判断收的卡片,可用
把可用的最小的卡片放到当前的盒子中
去下一个盒子放卡片
}
代码实现1
import java.util.Scanner;
public class Permute1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n + 1];
permute(1, n, arr);
}
public static void permute(int cur, int n, int[] arr) {
if (cur == n + 1) {// 1--n个盒子里都有数字
for (int i = 1; i <= n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
} else {
for (int i = 1; i <= n; i++) {
boolean flag = true;
for (int j = 1; j < cur; j++) {
if (arr[j] == i) {
flag = false;
}
}
if (flag) {
arr[cur] = i;
permute(cur + 1, n, arr);
}
}
}
}
}
代码实现2
import java.util.Scanner;
public class Permute2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
permute(0, n, arr);
}
public static void permute(int cur, int n, int[] arr) {
if (cur == n) {// 0--n-1个盒子里都有数字
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
} else {
for (int i = 0; i < n; i++) {
boolean flag = true;
for (int j = 0; j < cur; j++) {
if (arr[j] == i + 1) {
flag = false;
}
}
if (flag) {
arr[cur] = i + 1;
permute(cur + 1, n, arr);// 继续在下一个盒子放卡片
}
}
}
}
}
小结
如果某个问题的解可以由多个步骤得到,而每个步骤都有若干种选择(这些候选方案集可能会依赖于先前做出的选择),且可以用递归枚举法实现,则它的工作方式可以用解答树来描述
交换元素实现全排列
求所有排列的方法,就是上面所使用的 交换元素->递归->换回来 的思路。
例如:将 数组 { 1,2,3}进行全排列
首先,我们需要知道当只有一个元素进行全排列的时候,全排列就等于它本身。
这个数组的全排列就是需要将 每个元素放到数组首部,然后将剩下的元素进行全排列,依照此思路我们可以用递归很快的写出代码。
如果需要全排列按照字典序输出的话,只需要将需要全排列的数组先进行排序,然后再求全排列就好。
package LanQiaoVip_algorithm;
public class Permute3 {
public static void main(String[] args) {
int arr[] = { 1, 2, 3 };
permute(arr, 0, arr.length - 1);
}
public static void permute(int[] arr, int p, int q) {
// for循环将数组中所有的元素和第一个元素进行交换。然后进行全排列
// 递归结束条件
if (p == q) {
// 一次递归结束,将整个数组打印出来
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
for (int i = p; i <= q; i++) {
swap(arr, i, p);
// 把剩下的元素都做全排列
permute(arr, p + 1, q);
// 然后再交换回去,数组还原,保证下一次不会有重复交换
swap(arr, i, p);
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
变形后
package LanQiaoVip_algorithm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Permute {
static List<String> list=new ArrayList<String>();
public static void main(String[] args) {
int[]arr= {1,2,3};
permute(arr, 0);
for (String i : list) {
System.out.print(i+" ");
}
}
public static void permute(int[] arr,int start)
{
if (start==arr.length) {
list.add(Arrays.toString(arr));//把所有可能的全排列存放入list中
}
else {
for (int i = start; i < arr.length; i++) {
swap(arr,start,i);//交换元素
permute(arr, start+1);//交换后再进行全排列
swap(arr, start, i);//还原
}
}
}
private static void swap(int[] arr, int m, int n) {
int temp=arr[m];
arr[m]=arr[n];
arr[n]=temp;
}
}