面试题:字符串的排序
题目:
输入一个字符串,打印出该字符串中字符的所有排列
例如:输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba
思路:
对一个字符串进行全排列可分为两个问题:1.选择第一个位置的字符串;2. 对后面的子字符串进行全排列
递归过程
如长度为3的字符串,先固定第一个字符串,再对后面的长度为2的字符串进行全排列,即固定长度为2的字符串中的第一个位置,再对剩下长度为1的字符串进行全排列,此时输出排列的字符串
【注意】在对长度为n的字符串全排列时,会将第i个位置的字符与首位字符交换,在此次全排列结束后,需要将第i个位置的字符与首位字符换回来
举例:
对字符串abc来说,有三个字符,使用for循环来依次将三个字符都放在此时排列的字符串的第一个位置
(3长度循环)1. 先将a放在第一个位置,此时子字符串为bc,进入对bc的排列(for循环从i=0到i=len,会依次将第i个字符与第一个字符进行交换,使第i个字符被放到最前面,下面放置同理)
(2长度循环)a.子字符串bc中,先将b放在第一个位置,对c进行排列
(1长度循环)i.子字符串c中,此时将c放在第一个位置(abc),对空字符串进行排列
·待排字符串为空,打印当前字符串abc,返回到将c放在第一位置的操作,将c返回到交换前的状态,以不妨碍之后元素的交换(abc)
(1长度循环)ii. c之后没有下一个元素,因此返回到2中,将b返回交换前的状态(abc)
(2长度循环)b.子字符串bc中,现将c放到第一个位置,即交换c和第一个位置的字符(acb)
(1长度循环)i. 字符串b中,将b放在第一个位置,对空字符串进行排序
·待排字符串为空,打印当前字符串(acb), 退回7中,还原为bc
(2长度循环)无其他元素可进行排序,返回3长度循环中顺序(abc),还原a的调换(a与a的交换)
(3长度循环)2. 在字符串abc中,已将第一个元素放在首位,现将第二个元素放在首位,即b与首位字符交换(bac)
(2长度循环)a.在字符串ac中,先将a放在首位
(1长度循环)i.在字符串c中,将c放在首位
·在空字符串中,打印当前字符串(bac),返回字符串c中,无字符可排序,还原;返回字符ac中,还原
(2长度循环)b. 将c放在首位,交换位置(bca)
(1长度循环)i.在字符串a中,先将a放在首位
·在空字符串中,打印当前字符串(bca)
(1长度循环)ii.在字符串a中,无其他字符可排序,还原;
(2长度循环)c.返回字符ca中,无其他字符可排序,还原ca为ac;
第三个循环同理……
【注意】
如果面试需要按照一定要求摆放若干个数字,则可以先求出这些数字的所有排列,然后进行一一判断
【代码】
public class Q38 {
public static void main(String[] args) {
char[] array = new char[] {'a','b','c'};
permutation(array,0);
}
public static void permutation(char[] array,int start) {
if(array.length<0) {
return;
}
if(start == array.length) {
System.out.println(array);
}
for(int i=start;i<array.length;i++) {
swap(array, i, start);
permutation(array,start+1);
swap(array, start, i);
}
}
public static void swap(char[] array,int i,int j) {
char temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
【本题扩展】
求字符的所有组合
也是用递归完成
每次子串组合可分为两部分:组合中包含第一个字符/组合中不包含第一个字符
组合中包含第一个字符,则从子串后面选n-1个,
组合中不包含第一个字符,则从子串后面选n个
【代码】
public static void main(String[] args) {
char[] array = new char[] {'a','b','c','d'};
for(int i=0;i<array.length;i++) {
System.out.printf("len of subString:%d\n",i);
combinat(array,0,i,new StringBuffer());
}
}
public static void combinat(char[] array,int start,int i,StringBuffer stb) {
if(i==0) {
System.out.println(stb);
return;
}
if(start==array.length) {
return;
}
stb.append(array[start]);
combinat(array, start+1, i-1, stb);
stb.deleteCharAt(stb.length()-1);
combinat(array, start+1, i, stb);
}