字串的全排列

2021-08-07 02:38:53 字數 1689 閱讀 3977

點:理解全排列,遞迴的運用

題意:如字串abcd,獲取其全排列就是:abcd、abdc、acbd、acdb、adcb、adbc、

bacd、badc、bcad、bcda、bdca、bdac、

cbad、cbda、cabd、cadb、cdba、cdab、

dbca、dbac、dcba、dcab、dacb、dabc

共24種

劍指offer面試題28

思路:全排列是乙個較常見的題,表面感覺不特別難以理解,但實際做到真正理解和運用還是比較困難的:

簡單直觀的想,abc的全排列,abc、acb、bac、bca、cab、cba,就是字母a加上字母bc的兩個組合bc和cb,字母b加上ac的組合ac和ca,字母c加上ab的組合ab和ba

這就是:從簡單例子分析出規律,這點在面試時非常重要,因為很多使用動態歸劃、遞迴、以及一些需要洞察出其規律的題都是這樣,必須要洞察到規律,然後才能選擇正確的道路繼而寫的正確,如何洞察規律?就必須從簡單的例子中分析出;

如這個全排列,由上面的簡單例子的結果"字母a加上字母bc的兩個組合bc和cb,字母b加上ac的組合ac和ca,字母c加上ab的組合ab和ba",發現一種規律是:

依次以字串的每個字母為字首,加上其餘字母的排列組合,就是全排列。

而後面每個字母的排列組合,也同樣是乙個全排列問題。

再具體的看,abc,首先a做字首,然後是獲取bc的全排列,包括bc和cb,然後b做全排列。。。然後c做全排列;

大致乙個演算法的規律是:每個字母做字首,然後後面的子串也遞迴的這樣去幹,直到當前字串結束為止,然後遞迴回來繼續,比如abc,

1、a做字首去找bc的全排列

1.1、b做字首找c的全排列,就是c,輸出乙個abc

1.2、b和c交換,c做字首找b的全排列,就是b,輸出乙個acb

2、b做字首找ac的全排列

.............

3、c做字首找ab的全排列

.............

如果是更複雜的abcd呢?對於上面的第1步,a做字首找bcd的全排列,bcd的全排列的找法和abc的找法是一樣的。

至此基本明確了找的大致思路,並且很適應於遞迴,遞迴的停止條件是什麼?就是上面的第1步的b和c交換後,發現沒有可交換的餘地了。那麼遞迴不斷入棧的引數是?是當前準備要和其後面字串的字元們不斷交換的字元的位置,想象abcde的交換過程,假設在b和c交換後是acbde,位置是b的索引是2,接下來馬上就是b還要和b、d、e交換,這3個交換的遞迴過程,分別需要位置引數2、3、4。到e再遞迴時,也就是索引為4時再繼續遞迴時,就到了遞迴停止條件了,這時候設計為輸出當前字串的時候。

**很老套,關鍵還是理解思路。

全排列也是很多其他面試題的至少結果正確的解法。

每個字串全排列有多少種情況?乙個字元是一種,兩個字元是2個 *1 = 2種,3個字元是3個 * f(2) = 6種,4個字元是4個 * f(3) = 24種,也就是1*2*3*......n種,n是字串長度

**:

#include void swap (std::string &str, int i, int j) 

char t = str[i];

str[i] = str[j];

str[j] = t;

}void perm (std::string &raw, int idx, const int size) else

}}int main ()

字串的排列 全排列

輸入乙個字串,按字典序列印出該字串中字元的所有排列。例如輸入字串abc,則列印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。輸入乙個字串,長度不超過9 可能有字元重複 字元只包括大小寫字母。使用itertools中的permutations,可以實現全排列 ...

遞迴 字串全排列 全排列

在高中階段我們已經通過大量的習題了解了排列和組合。但是有時候我們研究的不是由排列和組合算出來的數字,研究的是生成排列和組合。即,把集合中元素所有的排列和組合全部列出來,然後研究這些序列的性質。今天我用兩種方法講一下如何生成排列。注意我們這裡涉及的順序都是序列的字典序。序列的字典序 設有兩個序列,第乙...

字串全排列

依次選出每乙個字元元素,作為排列的第乙個元素,然後對剩餘的元素進行全排列,如此遞迴處理,從而得到所有元素的全排列。以對字串abc進行全排列為例,我們可以這麼做 固定a,求後面bc的排列 abc,acb,求好後,a和b交換,得到bac 固定b,求後面ac的排列 bac,bca,求好後,c放到第一位置,...