递归问题的解决思路

什么是递归呢? 即程序反复调用自己。

在面对递归问题的时候,不要纠结于这一层做了什么,返回是什么,下一层又做了什么。

递归既然是一个反复调用自己的过程,那么他的每一步一定都是一样的,因此我们只需要关注这一级的解决过程。

p1

像上面一样 , 需要关注三点:

1. 整个递归的终止条件;

2.一级递归需要做什么;

3. 应该给上一级返回什么;

因此,也就有了我们解递归题的三部曲:

  1. 找整个递归的终止条件:递归应该在什么时候结束?

  2. 找返回值:应该给上一级返回什么信息?

  3. 本级递归应该做什么:在这一级递归中,应该完成什么任务?

例题1. 求二叉树的最大深度

1. 整个递归的终止条件: 什么情况下结束递归? 当树的深度为0的时候,结束递归

2. 返回值是什么?  题目要求返回值是树的最大深度,我们每一级的返回值就是当前树的最大深度。

3. 本级递归应该做什么? 走出之前的思维误区,一定不要去管树的下一级是什么。递归之后的树一定是这个样子的。看下图:

p2

此时的树只有三个结点: 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 和 处理完的链表。而本级的递归任务也就是交换这个三个节点中的前两个节点。

p3

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

 

 

 

--------------------------------------------------

转自:http://39.96.217.32/blog/4

  • 作者:刘宇麟(联系作者)
  • 发表时间:2019-05-17 22:42
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请通过邮箱联系作者!
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值