什么是递归呢? 即程序反复调用自己。
在面对递归问题的时候,不要纠结于这一层做了什么,返回是什么,下一层又做了什么。
递归既然是一个反复调用自己的过程,那么他的每一步一定都是一样的,因此我们只需要关注这一级的解决过程。
像上面一样 , 需要关注三点:
1. 整个递归的终止条件;
2.一级递归需要做什么;
3. 应该给上一级返回什么;
因此,也就有了我们解递归题的三部曲:
-
找整个递归的终止条件:递归应该在什么时候结束?
-
找返回值:应该给上一级返回什么信息?
-
本级递归应该做什么:在这一级递归中,应该完成什么任务?
例题1. 求二叉树的最大深度
1. 整个递归的终止条件: 什么情况下结束递归? 当树的深度为0的时候,结束递归
2. 返回值是什么? 题目要求返回值是树的最大深度,我们每一级的返回值就是当前树的最大深度。
3. 本级递归应该做什么? 走出之前的思维误区,一定不要去管树的下一级是什么。递归之后的树一定是这个样子的。看下图:
此时的树只有三个结点: root ,root.left, root.right。其中根据第二步,root.left 和 root.right分别记录的是root的左右子树的最大深度。那么本级递归应该做什么就很明确了。自然是在本级中寻找更大的一个,再加上1就是以root为根的子树的最大深度,再返回这个深度就可以了!
def treeDepth(root):
if not root: # 终止条件
return 0
# 左右子树的最大深度
left = treeDepth(root.left)
right = treeDepth(root.right)
# 返回左右子树的最大深度+1
return max(left, right) + 1
例题2 两两交换链表中的节点
1. 终止条件:什么时候终止呢? 没得换的时候就终止了。 因此当链表中只剩下一个节点或则没有节点时,递归自然就终止了。
2. 找返回值: 我们需要像上一级返回什么信息呢?由于我们已经两两交换了链表中的相邻节点了, 因此自然希望交给上一级的是已经交换完成的链表;
3. 本级递归应该做什么?看图。由于我们只考虑本级的递归。那么链表在我们眼中只有三个点 head head.next 和 处理完的链表。而本级的递归任务也就是交换这个三个节点中的前两个节点。
def swapPairs(head):
if not head or not head.next:
return head
# 在我们眼里每次递归只有三个部分
# head next swapPairs(next.next)
# 这次的任务就是交换head 和 next
next = head.next
# 交换head 和 next
head.next = swapPairs(next.next)
next.next = head
return next
例题三 平衡二叉树
1. 终止条件: 什么下递归会终止? 当子树是空的时候就停止,空树自然是平衡二叉树
2. 应该返回什么信息: 我们到底希望返回什么呢???
什么是平衡二叉树?平衡二叉树就是左右子树差值不超过1的二叉树。
对于一棵树他是平衡二叉树要满足三个条件: 左子树是平衡二叉树, 右子树是平衡二叉树, 左右子树的高度差不超过1。也就是说 他的左子树 右子树 不是平衡二叉树,或则他们的左右子树的高度差大于1, 那么他就不是平衡二叉树。
而在我们眼里,这颗二叉树就3个节点:root、left、right。那么我们应该返回什么呢?如果返回一个当前树是否是平衡二叉树的boolean类型的值,那么我只知道left和right这两棵树是否是平衡二叉树,无法得出left和right的高度差是否不大于1,自然也就无法得出root这棵树是否是平衡二叉树了。而如果我返回的是一个平衡二叉树的高度的int类型的值,那么我就知道两棵树的高度了。
3 . 本级要做什么? 知道了第二步,我们每次返回之前的子树的高度即可。我们计算得到的高度差 如果大于1就返回False ,不是的话就返回该子树下面的左子树和右子树,继续之前的比较。
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root: # 终止条件
return True
# 得到高度进行比较
left = self.helper(root.left)
right = self.helper(root.right)
if abs(right-left) > 1:
return False
# 返回的信息 要么False 要么继续
return self.isBalanced(root.left) and self.isBalanced(root.right)
def helper(self, root):
if not root:
return 0
left = self.helper(root.left)
right = self.helper(root.right)
return max(left, right) + 1
--------------------------------------------------
- 作者:刘宇麟(联系作者)
- 发表时间:2019-05-17 22:42
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
- 公众号转载:请通过邮箱联系作者!