全排列
给定一个n,返回1, 2, 3, ... , n 的全排列。
这里给出两种方法。它们的时间复杂度都是O(n!),因为n的全排列有n!种。
1.基于以下观察:第k个位置可以是1, 2, 3, ... , or n。如,第一个位置可以是1, 2, 3, ... , or n,在确定这个位置的数后,那么第二个位置的数就可以是除已确定的数之外的数,如此类推,知道确定到第n-1个位置上的数(此时第n个位置的数显然也确定了)。
例如,n=3,
全排列(和代码输出的可能略有差异,但思路是这样):
1, 2, 3
1, 3, 2
2, 1, 3
2, 3, 1
3, 1, 2
3, 2, 1
2.基于以下观察:k 可以放在第1, 2, 3, ... , or n 个位置。如,n可以放在第1, 2, 3, ... , or n 个位置,确定n后,再确定n-1放在哪个位置,一直到确定1放在哪个位置。
例如, n=3,
全排列(和代码输出的可能略有差异,但思路是这样):
3, 2, 1
3, 1, 2
2, 3, 1
1, 3, 2
2, 1, 3
1, 2, 3
import java.util.Arrays; public class permutations{ private static int[] A; private static int count; private static int factorial(int n){ //return n! if(n == 0)return 1; return n*factorial(n-1); } private static void swap(int i, int j){ //swap A[i] and A[j] int tmp = A[i]; A[i] = A[j]; A[j] = tmp; } public static void perm1(int k){ //generate permutations of A if(k == A.length-1){ System.out.println(Arrays.toString(A)); count ++; } else{ //the kth place can be 1, 2, 3, ... , n-1 or n for(int i = k; i < A.length; i ++){ swap(i, k); perm1(k+1); swap(i, k); } } } public static void perm2(int k){ //generate permutations of A if(k == 0){ System.out.println(Arrays.toString(A)); count ++; } else{ //k can be at the 1st place, the 2nd place, ... , or the nth place for(int i = 0; i < A.length; i ++){ //A[i] = 0 indicates that the ith place is still empty if(A[i] == 0){ A[i] = k; perm2(k-1); A[i] = 0; } } } } public static void main(String[] args){ //Unit testing int n = 3; A = new int[n]; count = 0; for(int i = 0; i < A.length; i ++){ A[i] = i+1; } perm1(0); //verify the result is correct System.out.println(count); System.out.println(count == factorial(A.length)); count = 0; for(int i = 0; i < A.length; i ++){ A[i] = 0; } perm2(A.length); //verify the result is correct System.out.println(count); System.out.println(count == factorial(A.length)); } }