刷力扣学习递归
原题链接
https://leetcode-cn.com/problems/add-two-numbers/submissions/
https://leetcode-cn.com/problems/generate-parentheses/submissions/
递归简单来说就是一个自己调用自己的函数,以此来实现一个类似于循环的过程
。
递归理解起来很简单,之前不是有一个故事嘛,两个人比赛画马,看谁画的多,其中一个人画了几天几夜,另一个人却画了一座山,山前露出一个马头,山下露出一条马尾巴,看起来就好像是千军万马再行军了。递归也是如此,先写出一个循环部分,再写出递归的结束条件,执行的时候输入开始数据,大军就行进起来了。
递归主要分为两种,普通递归与尾递归,下面就是两种递归方法求得1到100的累加
#普通递归
def foo1 (n):
if n>=100:
return n
else: return n + foo1(n+1)
#尾递归
def foo2 (sum,n):
if n <= 100:
next_sum = n + sum
foo2(next_sum,n+1)
else: return sum
可见,与普通递归相比,尾递归两次调用函数之间的联系是没有那么大的,绝大多数尾递归都能改写为循环,而有的解释器甚至可以专门做到这一点来提高效率。
题解
我在力扣上写了几道递归的题目,得出了一些自己的总结
- 如果递归中有循环,而每一条分支互不相关,那么之间传递的数据最好包含在一个参数里面(题22)
- 链表本身就是包含了一个递归在里面,用递归解决会很方便(题2)
下面我写的答案,速度都超过90%的用户,本身技术有限,也放在这里了
#2. 两数相加
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
def foo (n,m,extra):
dummy = ListNode()
val = n.val+m.val+extra
dummy.val = val%10
extra = val//10
if n.next or m.next:
if not n.next:
n.next = ListNode()
if not m.next:
m.next = ListNode()
#递归调用
dummy.next = foo(n.next,m.next,extra)
return dummy
else:
if extra:
dummy.next = ListNode(extra,None)
return dummy
return foo(l1,l2,0)
#22. 括号生成
def generateParenthesis(self, n: int) -> List[str]:
answer = []
def dfs (s,flag,site):
if site == n:
answer.append(s + '(' + ')'*(n-flag))
return
for i in range(site-flag+1):
#递归调用
dfs(s + '(' + ')' * i ,flag+i,site+1)
dfs('',0,1)
return answer