题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。

import java.util.ArrayList; public class Solution{ static ArrayList<String> list=new ArrayList<String>(); public static void swap(char[] ch,int i,int j){ char temp=ch[i]; ch[i]=ch[j]; ch[j]=temp; } public static void permutation(char[] chArr,int index){ if(chArr==null||chArr.length==0){ return; } if(index==chArr.length){ list.add(String.valueOf(chArr)); } for(int i=index;i<chArr.length;i++){ swap(chArr,i,index); permutation(chArr,index+1); swap(chArr,i,index); } } public static void main(String[] args){ String str="abc"; char[] chArr=str.toCharArray(); permutation(chArr,0); for(String s:list){ System.out.println(s); } } }
题目扩展,求字符的所有组合。还是输入三个字符a、b、c,则它们的组合有a、b、c、ab、ac、bc、abc。当交换字符串中的两个字符时,虽然能得到两个不同的排列,但却是同一个组合。ab和ba是同一个组合。
如果输入n个字符,则这n个字符能构成长度为1的组合、长度为2的组合、...、长度为n的组合。在求n个字符的长度为m(1<=m<=n)的组合时候,把n个字符分成两个部分:第一个字符和其余的所有字符。如果组合里包含第一个字符,则下一步在剩余的字符里选取m-1个字符;如果组合里不包含第一个字符,则下一步在剩余的n-1个字符里选取m个字符。也就是说,可以把求n个字符组成长度为m的组合的问题分解成两个子问题,分别求n-1个字符串中长度为m-1的组合,以及求n-1个字符的长度为m的组合。
代码实现:
import java.util.ArrayList; public class Solution{ public static void combination(char[] array){ //判断数组是否有值 if(array==null||array.length==0){ return; } ArrayList<Character> list=new ArrayList<>(); //从0开始,获取长度为1的组合,长度为2的组合,...长度为n的组合 for(int i=1;i<=array.length;i++){ combine(array,0,i,list); } } public static void combine(char[] array,int begin,int number,ArrayList<Character> list){ //number为0,表示已经组合完成,输出结果 if(number==0){ System.out.println(list.toString()); return; } //已经跳到最后,但组合并未完成,组合无效返回 if(begin==array.length){ return; } //包含第一个字符,在剩余的字符中选取number-1个字符 list.add(array[begin]); combine(array,begin+1,number-1,list); //不包含第一个字符,在剩余的字符中选取number个字符 list.remove(list.size()-1); combine(array,begin+1,number,list); } public static void main(String[] args){ String s="abc"; char[] charArr=s.toCharArray(); combination(charArr); } }
posted on
浙公网安备 33010602011771号