问题描述
实现字符串的全排列,比如 用户输入“abcd”,则会输入如下4!个字符串
a b c d
....
....
d c b a
实现方式两种:
- 递归
- 非递归
工具类方法
/**
* 遍历打印 字符串
* @param str
*/
private static void printCharArr(char[] str) {
for (char c :
str) {
System.out.print(c + " ");
}
System.out.print("\n");
}
递归实现
通过方法的递归调用 ,将问题规模降低。
/**
* 打印字符串
* @param str
* @param index
*/
public static void printAllStrs(char[] str,int index){
if(index==str.length-1){
//打印当前数组
printCharArr(str);
return;
}
for (int i = index; i < str.length; i++) {
if(isCanSwap(index,i,str)){
//将index之后的某个元素与index位置的原生进行交换
//然后打印全排列
swap(i,index,str);
printAllStrs(str,index+1);
//还原数据的位置
swap(i,index,str);
}
}
}
/**
* 去重
* @param start
* @param start
* @param str
* @return
*/
private static boolean isCanSwap(int start, int end, char[] str) {
char target = str[end];
while (--end>=start){
if(str[start]== target)
return false;
}
return true;
}
/**
* 交换位置
* @param start
* @param end
* @param str
*/
public static void swap(int start,int end, char[] str){
char tmp = str[start];
str[start] = str[end];
str[end] = tmp;
}
非递归
/**
*
* 实现的思想是 从最小值到最大值,依次递增
*
* 递增实现的步骤如下:
*
* 步骤: 假设输入的数组为 s = '15976'
* 1. 首先排序(从小到大)
* 2. 从后往前找到第一个递增位置的元素 i (比如'15976' 的最后一个递增位置索引是 1)
* 3. 然后找到从第i位置往后找,找到一个比s【i】大的,且最小的元素s[j] (改元素的索引位置j).
* 4. 将s[j]与s[i]交换位置
* 5. 将i+1之后的元素进行翻转
* 6. 直到不存在递增的元素位置而止
*
* 全排列 非递归
* 12345 -> 12354 -> 12354
* 12354 -> 124 53 -> 12435
*
* 21534 -> 2154 3-> 21543
* 21543 -> 2 3541 -> 23145
*
*
* @param str
*/
public static void printAllStrs(char[] str){
while (true){
//先找到最后一个递增的位置
int i = str.length-2;
while (i>=0&&str[i]>str[i+1]){
i--;
}
if(i<0){
break;
}
char tmp = str[i];
//将该位置数据和 右侧比起大的最小值进行交换
char smallerValue = str[i+1];
int smallerIndex= i+1;
for (int start = i+1;start<str.length;start++){
if(str[start]>tmp&&smallerValue>str[start]){
smallerIndex = start;
smallerValue = str[start];
}
}
//交换
str[i] = str[smallerIndex];
str[smallerIndex] = tmp;
int startIndex = i+1;
int postPtr = str.length-1;
//将该位置的往后的数据进行翻转
while (startIndex<postPtr){
char tmp2 = str[startIndex];
str[startIndex] =str[postPtr];
str[postPtr] = tmp2;
startIndex++;
postPtr--;
}
//打印数据
printCharArr(str);
}
}