递归实现全排列(盒子放卡片思维与交换元素思维)

1. 题目描述

在这里插入图片描述

2. 思路图解

在这里插入图片描述

  • 往盒子里放卡片
  • 判断是假想的盒子吗?
  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;
	}

}

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:精致技术 设计师:CSDN官方博客 返回首页
评论

打赏作者

Sparky*

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值