前言:在笔试和面试的过程中,多次遇到字符串的全排列问题,这里实现两个典型的例子,用来加深一下理解,大家可以参考参考。
题目1描述:输入为{'a','b','c'},则输出其全排列为:abc, acb, bac, bca, cba, cab。若输入的是一个长度为n的字符数组,则全排列的组合为n!个。
题目2描述:输入为{'a','b',‘b’,'c'},则输出其不重复的全排列,结果如下:
[a, b, b, c]
[a, b, c, b]
[a, c, b, b]
[b, b, a, c]
[b, b, c, a]
[b, a, b, c]
[b, a, c, b]
[b, c, a, b]
[b, c, b, a]
[c, b, b, a]
[c, b, a, b]
[c, a, b, b]
代码如下:
public class FullPermutation {
/**
* @author Norte
*
* Date:2018-07-26
*
* 功能:字符串的全排列
*
* 基本思想:每次从字符数组中选取一个元素(从第一个开始到最后一个结束),作为结果的第一元素,剩下的元素做全排列,
* 很明显这是一个递归的过程,递归结束标志为所选取的元素为字符数组的最后一个元素
* */
public static void finishFullPermutation(char[] array) {
permutation(array, 0, array.length);
}
public static void permutation(char[] array, int start, int end) {
if(end < 0) { //字符数组中没有元素直接返回
return;
}
if(start == end) {
System.out.println(array);
}else {
for(int i = start; i < end; i++) {
swap(array, i, start); //更换前缀
permutation(array, start + 1, end); //递归将剩余元素全排列
swap(array, start, i); //将前缀换回,以便进行上一个前缀的全排列
}
}
}
public static void swap(char[] array, int i, int j) { //用来交换前缀
char tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public static void main(String[] args) {
char[] array = {'a','b','c'};
finishFullPermutation(array);
}
}
运行结果如下:
abc
acb
bac
bca
cba
cab
代码如下:
public class RealFullPermutation {
/**
* @author Norte
*
* Date:2018-07-26
*
* 功能:字符数组中的字符有重复元素,实现不重复的全排列组合
*
* 基本思想:在实现全排列的基础上,将结果进行筛选,将全排列的结果放在一个list中,放入之前通过contains()方法,
* 进行判断,如果list中已经包含该组合,则该组合不放入list中。
*
* */
public static List list = new ArrayList<>();
public static void finishFullPermutation(char[] array) {
if(list != null) { //调用该方法前判断存放组合的list是否为空,也顺便解决了多次调用要清空list的问题
list.removeAll(list);
}
permutation(array, 0, array.length);
}
public static void permutation(char[] array, int start, int end) {
if(end < 0) {
return;
}
if(start == end) {
String node = Arrays.toString(array); //将组合转换为字符串方便判断
if(!list.contains(node)) { //判断该组合在list中是否已经存在
list.add(node);
System.out.println(node); //打印list中的组合
}
}else {
for(int i = start; i < end; i++) {
swap(array, i, start);
permutation(array, start + 1, end);
swap(array, start, i);
}
}
}
public static void swap(char[] array, int i, int j) { //用来交换前缀
char tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public static void main(String[] args) {
char[] array = {'a','b','b','c'};
finishFullPermutation(array);
}
}
运行结果如下:
[a, b, b, c]
[a, b, c, b]
[a, c, b, b]
[b, a, b, c]
[b, a, c, b]
[b, b, a, c]
[b, b, c, a]
[b, c, b, a]
[b, c, a, b]
[c, b, b, a]
[c, b, a, b]
[c, a, b, b]