在这篇文章里,我们将基于力扣两道题目,分析递归的方法,并最后给出一个递归写法的模板
目录
括号生成
第一道题目是括号生成,
我们需要生成给定对数的合法括号排列,且我们需要给出所有合法形式
此处递归的写法是:
如果需要我们生成n对括号,
那么我们采用递归的形式生成所有2n长度的括号排列,
并从这里面选取所有合法的括号排列
对应代码如下:
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
def generate(l: list):
if(len(l) == 2*n):
if(valid(l)):
ans.append(''.join(l))
else:
l.append('(')
generate(l)
l.pop()
l.append(')')
generate(l)
l.pop()
def valid(l: list):
cnt = 0
for s in l:
if(s == '('):
cnt = cnt + 1
else:
cnt = cnt - 1
if(cnt < 0):
return False
return cnt == 0
ans = []
generate([])
return ans
电话号码的字母组合
第二道题目是 电话号码的字母组合
每一个号码都对应一串字符串,
那么我们连续输入几个号码,输出数字长度的所有字符排列
对应代码如下:
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
d_str_map = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
}
def generate(index):
if(len(combination) == len(digits)):
combinations.append(''.join(combination))
else:
digit = digits[index]
d_str = d_str_map[digit]
for s in d_str:
combination.append(s)
generate(index+1)
combination.pop()
index = 0
combination = []
combinations = []
if(not digits):
return combinations
generate(index)
return combinations
递归写法模板
我们分析上面两道题目,发现递归写法的生成方式对应一棵树:
递归的写法,是对树的深搜写法。
例如对于“括号生成”题目:
生成所有长度为4的序列,以深度优先的方式,生成所有序列
但其实,我们在这4层树,对应一个长度为4的栈,它会压入括号,再弹出括号
在代码中,就对应generate函数中的l列表
那么我们可以归纳出递归写法的模板:
对于每一次生成的子节点,子节点的个数都多少个,
同一层次,具体的递归算法就要调用多少次(注意他们是同一层的)
不考虑这个递归算法再往深调用的递归算法
模板如下:
digui(){
if(len(combination) == 要生成的长度): //每一个分支的结束,已经完成了一个分支的叶子节点的生成
combinations.append(combination) //combinations为结果集,一个分支结束,若符合要求,则保存下来
else: //如果一个分支还没有生成结束,则继续生成
for i in llist: //llist指每一层要生成的子节点列表
combination.append(i) //combination即提到那个栈,也是我们要的一个结果
digui() //往深一层调用递归算法
combination.pop() //栈弹出一个元素,(循环的这一次结束,将在栈的这同一位置压入要循环的下一个元素)
}