对于简单的递归(能够写出数学表达式的递归),咱们已经熟练掌握,可是对于有些递归咱们有时候无从下手。这时候咱们须要将抽象的问题数学化,或者能表达出来。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: