题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串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 2018-11-08 22:21  会飞的金鱼  阅读(140)  评论(0)    收藏  举报