【代码+详解】算法题 : 全排列

❗❗❗必看:
下列题我全部都使用 Java 语言写的,并且均可以提交成功,获得Accepted 结果的. 如果代码和详解看了之后,对答案有任何疑问,都可以在评论区提出来,我都会一个一个回答.

❗❗❗感谢大家的支持,如果喜欢我的博客,关注 点赞 收藏 评论一波,非常感谢!!!

题目 : 全排列

对于数组[1, 2, 3],他们按照从小到大的全排列是

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

现在给你一个正整数n,n小于8,输出数组[1, 2, …,n]的从小到大的全排列。

Input

输入有多行,每行一个整数。当输入0时结束输入。

Output

对于每组输入,输出该组的全排列。每一行是一种可能的排列,共n个整数,每个整数用一个空格隔开,每行末尾没有空格。


样例测试

输入

2
3
0

输出

1 2
2 1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1


代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

//全排列
public class Main {
	
public static void main(String[] args) {
	//输入
	Scanner scanner = new Scanner(System.in);
	List<Integer> inputs = new ArrayList<>();
	
	//把输入的待求全排列的数据全部都填充到inputs顺序表中,目的是后续方便管理,因为我们要对这些输入的数据进行遍历
	while(scanner.hasNextInt()) {
		int n = scanner.nextInt();
		if(n!=0) {
			inputs.add(n);
		}else {
			break;
		}
	}
	
	//遍历输入的待求全排列的数据,并把其初始化
	for(int n:inputs) {
	int[] array = new int[n];
	for(int i = 0;i<n;i++) {
		array[i] = i+1;
	}
	
	//然后把当前生成的array数组存到我们的新顺序表,准备这个是用来保存我们的结果的数组
	 List<List<Integer>> result = new ArrayList<>();
     generatePermutations(array, 0, result);
	
     //字典顺序排序
     Collections.sort(result, (a, b) -> {
         for (int i = 0; i < a.size(); i++) {
             if (!a.get(i).equals(b.get(i))) {
                 return a.get(i) - b.get(i);
             }
         }
         return 0;
     });
     
     
     // 输出结果
     for (List<Integer> permutation : result) {
         for (int i = 0; i < permutation.size(); i++) {
             System.out.print(permutation.get(i));
             if (i < permutation.size() - 1) {
                 System.out.print(" ");
             }
         }
         System.out.println();
     }
 }

 scanner.close(); 
     
     }


	//递归函数
public static void generatePermutations(int[] array, int start, List<List<Integer>> result) {
    if (start == array.length - 1) {
        // 当 start 达到数组的最后一个位置时,说明当前排列已经完成
        List<Integer> permutation = new ArrayList<>();
        for (int num : array) {
            permutation.add(num);
        }
        result.add(permutation); // 将当前排列添加到结果列表中
    } else {
        // 对 start 及其后的每个位置进行排列
        for (int i = start; i < array.length; i++) {
            swap(array, start, i); // 交换当前元素和 start 位置的元素
            generatePermutations(array, start + 1, result); // 递归生成子排列
            swap(array, start, i); // 复原数组
        }
    }
}
//交换数组中的两个元素
public static void swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

}

初步思路

利用递归生成数组的全排列,并使用交换元素的方法逐步生成所有排列。

具体步骤

  1. 输入处理

    • 使用 Scanner 读取多行输入,每行一个整数。
    • 将每个输入整数 n 存入列表 inputs 中,直到遇到0为止。
  2. 初始化数组

    • 遍历 inputs 列表,对于每个 n,初始化一个数组 array,其中包含 [1, 2, …, n]。
  3. 递归生成全排列

    • 调用 generatePermutations 方法,递归生成数组的全排列。
    • 在每次递归调用中,固定一个元素,然后对剩余元素进行全排列。
  4. 交换元素

    • 使用 swap 方法交换数组中的两个元素,这样可以固定一个元素,然后递归生成其余元素的全排列。
  5. 恢复数组状态

    • 在递归调用后,将数组恢复原状,以便进行下一次排列的生成。
  6. 字典序排序

    • 使用 Collections.sort 方法对结果列表 result 按字典序排序。
    • 自定义比较器逐元素比较排列中的数字,保证按字典序排列。
  7. 输出结果

    • 遍历 result 列表,按格式输出每个排列。

总结方法

  • 递归与回溯:通过递归生成全排列,并在每次递归后恢复数组状态,实现回溯。
  • 字典序排序:通过逐元素比较排列中的数字,确保输出的全排列按字典序排列。
  • 元素交换:使用元素交换方法固定部分排列,递归生成其余排列。
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值