【劍指offer】字符串的排列

 問題描述:

 輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

 輸入描述:

輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。

分析:

這個題的主要難點在於每個字符的所有排列,下面用的方法是使用遞歸來實現的,如圖(用ABC來舉例)。

過程:(遞歸這一塊可能描述的不是那麼準確)

當剛進去totalOrder這個方法時,此時 index 值爲 0,此時他指向的是第一個元素A(在for循環中,它可以交換3次,和自己交換(沒有變化),和第二個元素B交換,和第三個元素C交換),道理都是一樣的,所以只詳細講一種。當他和自己交換後,然後遞歸進行下一次調用,此時傳入的 index 值已經加一了,也就是說,現在index所指向的是第二個數(有兩次交換機會,和自己,和後面的數),他和自己交換,此時他有進入了下一次的遞歸調用中,因爲他現在已經是最後一個數了,所以將它現在的字符串(ABC)放到list中。然後進行回退,因爲他和自己已經交換了,那麼他就只有和他後面的那個數進行交換,然後又一次進行遞歸,此時他指向最後一個數,所以將它現在的字符串(ACB)再次放到list中,他就開始一層一層回退回去,然後有一次進行交換,遞歸操作,依次類推下去,就能得到字符串的所有排列了。

代碼:

import java.util.*;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        List<String> list = new ArrayList<String>();
        if(str != null && str.length()>0){
            totalOrder(str.toCharArray(),0,list);
            Collections.sort(list);
        }
        return (ArrayList)list;
    }
    public void totalOrder(char[] chars,int index,List<String> list){
        if(index == chars.length-1){
            String value = String.valueOf(chars);
            if(!list.contains(value)){
                list.add(value);
            }
            
        }else{
            for(int i = index;i<chars.length;i++){
                swap(chars,i,index);
                totalOrder(chars,index+1,list);
                swap(chars,i,index);
            }
        }
    }
    public void swap(char[] s,int i,int j){
        char tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章