對於簡單的遞歸(能夠寫出數學表達式的遞歸),咱們已經熟練掌握,可是對於有些遞歸咱們有時候無從下手。這時候咱們須要將抽象的問題數學化,或者能表達出來。app
(本節須要掌握: 熟悉遞歸函數的返回是一個什麼???)函數
例1:字符串的全排列問題(劍指offer)spa
輸入一個字符串,按字典序打印出該字符串中字符的全部排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的全部字符串abc,acb,bac,bca,cab和cba。code
首先咱們考慮該問題是不是能夠用相同方法解決? 對於abcd例子blog
① a b c d 的排列咱們首先用表達式表達 Perm(a b c d) 這個表示對 abcd全排列遞歸
② 而後發現把abcd 全排列就能夠轉化爲 把 a打頭 對 bcd 全排列Perm(b c d) b打頭 對 acd 全排列Perm(a c d) rem
c打頭 對 abd 全排列Perm(a b d) d打頭 對 abc 全排列Perm(a b c)字符串
③ 這個就不是很簡單的遞歸了,這須要咱們加入一些條件(循環),來讓它執行遞歸過程。 其實第二個過程就是一個循環的過程數學
1 def prem(abcd): 2 for i in abcd: 3 i + prem(沒有i的字符串) 咱們能夠保留的結果
這裏咱們假設 prem返回的就是 一些字符的排列組合的結果。
好比a + prem(cd) 就至關於 a + [cd, dc] ----> acd adc
注意 : (這個理解了就很簡單了)it
④ 這時候咱們還有十分重要的一步(遞歸出口在哪呢???) 咱們將問題一步步分解,發現 例如 abc排好了 剩下d 一個了,那就不須要執行prem了。
出口就是: 當爲一個字符時結束
1 def Permutation(ss): 2 # write code here 3 result = [] 4 if not ss: 5 return [] 6 if len(ss) ==1: #出口 7 return [ss] 8 for i in range(len(ss)): #分別固定每個開頭 9 temp = Permutation(ss[:i] + ss[i+1:]) #排列剩下的, 假設返回一個列表結果 10 for j in temp: 11 result.append(ss[i] + j) #保存結果,這部分很難理解 只須要理解第三步就很好理解了 12 return list(set(result))
例2: