给定一个字符串,打印对应的全排列数组,比如abc,对应的全排列是:abc,acb,bac,bca,cba,cab。
下面分析下思路是什么样的。基本的思路是这样的,首先固定一个字符,比如a,计算剩余字符的全排列,也就是bc的全排列,此时固定b,计算剩余字符的全排列,也就是c的全排列,但是因为begin=end所以此时打印字符串,接着交换bc,再继续打印,
代码:
public class Main { static void permutation(char[] chars) { permutation(chars, 0, chars.length - 1); } /** 数组中从索引begin到索引end之间的子数组参与到全排列 */ static void permutation(char[] chars, int begin, int end) { if (begin == end) { //只剩最后一个字符时为出口 for (int i = 0; i < chars.length; ++i) { System.out.print(chars[i]); } System.out.println(); } else { for (int i = begin; i <= end; i++) { //每个字符依次固定到数组或子数组的第一个 if (canSwap(chars, begin, i)) { //判断是否重复了 swap(chars, begin, i); // permutation(chars, begin + 1, end); //递归求子数组的全排列 swap(chars, begin, i); //还原 } } } } //如果时重复字符串,就放弃交换,比如abb,第2次交换就没有必要了 static boolean canSwap(char[] chars, int begin, int end) { for (int i = begin; i < end; ++i) { if (chars[i] == chars[end]) { return false; } } return true; } static void swap(char[] chars, int from, int to) { char temp = chars[from]; chars[from] = chars[to]; chars[to] = temp; } public static void main(String[] args) { final char[] chars = new char[] {'a', 'b', 'c'}; permutation(chars); } }
参考文献: