java实现全排列 & java实现next_permutation()
基于递归数组交换的实现
若不考虑全排列的顺序,那么可以用较简单的方法实现:
通过按层交换两个元素位置实现n个数的全排列。
效率高,程序便于编写。但输出的序列并非字典序。
import java.util.*;
import java.math.*;
public class Main {
public static void permutation(int x, int[] arr){
if(x==arr.length) {//输出找到的全排列
for(int it:arr)
System.out.printf("%5d",it);
System.out.println();
}
for(int i = x; i < arr.length;i++){//从x位置向后交换
{int y = arr[x];arr[x] = arr[i];arr[i] = y;}//swap(arr[x],arr[i])
permutation(x+1,arr);
{int y = arr[x];arr[x] = arr[i];arr[i] = y;}//swap(arr[x],arr[i])
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++)
a[i]=i+1;
permutation(0, a);
}
}
下面进入正题
P1706 全排列问题 - 洛谷
题目描述
输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n。
输出格式
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5 个场宽。
输入输出样例
输入 #1 | 输出 #1 |
---|---|
3 | 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 |
说明/提示
1≤n≤9
程序
java的自带函数中不存在next_permutation()函数导致做一些题目可能会比较复杂。
详细解释请对照注释。
该方法能确保求出的下一排列数满足大小顺序。
证明:
考虑序列a[6]
,任取其一种排列{2, 3, 1, 4, 6, 5}
,由定义知下一排列为{2, 3, 1, 5, 4, 6}
。在原序列中{6, 5}
为尾部的最长降序序列,由定义知无下一排列。现在扩展到原序列子序列{4, 6, 5}
;若保证下一字典序升序排列只需swap(4,min{5,6}),并使其子序列{5, 6}
最小序即可。据字典序有大于该序列的最小项{5, 4, 6}
。
同理推广至n元素的下一排列同样有效。证毕。
该方法思维量不大且效率较高 (主要是好想,实测比c++的stl慢好多(本身java也比c++慢一些…))。
够 用 就 彳亍
import java.util.*;
import java.math.*;
public class Main {
public static boolean nextPermutation(int[] arr) {
int i = arr.length - 2;
while (i >= 0 && arr[i] > arr[i + 1]) // 从后往前找,找到第一个不满足降序的数(要考虑到重复的数字)
i--;
if (i == -1)
return false;
int k = i + 1;
while (k < arr.length && arr[k] > arr[i]) // 从i开始往后找到大于arr[i]的最小的数
k++;
{ int tmp; tmp = arr[i]; arr[i] = arr[k - 1]; arr[k - 1] = tmp; } // 交换arr[i]和arr[k-1]
Arrays.sort(arr, i + 1, arr.length); // 重新对arr[i]后面的数排序,接下来继续进行全排列操作
return true;
}
public static void main(String[] args) { //利用nextPermutation求全排列的功能演示
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++)
arr[i]=i+1;
do {
for (int i = 0; i < n; i++) {
System.out.printf("%5d",arr[i]);
}
System.out.println();
} while (nextPermutation(arr));
}
}