开荒新系列之LeetCode: 002-Maximum Depth of Binary Tree

总结讨论

在不看上一篇文章的前提下,回忆总结一下上次工作,看看到目前为止还记得多少:

  • 要多手写一些测试数据
  • 不止一种方法实现,寻找最简单的方法
  • python is 比 == 要快一点点

Maximum Depth of Binary Tree

题目大意:找二叉树的最大深度。

基本思路:除了DFS(Depth-Fisrt-Search),还有其它办法吗?直觉上并没有了呃,但是仔细想想,只要是能够遍历二叉树的方法都是可以的,比如BFS(广度优先算法)。(有没有快过这两类算法的方法呢?)

所以第一方案还是使用DFS。老实说DFS已经很久没有写过了,但是大概原理还记得是怎么回事。

左子树的DFS算法

左子树的DFS算法,概括来说就是先看左边的,左边的看完了看右边的,右边的看完往回退一步,再看右边的。
写成伪代码是:
1. 从Node_Root出发
2. 对于Node_Now(Parent -> Node_P, Child_Left -> Node_NL, Child_Right -> Node_NR) 的左子树进行如下判断:
2-1. 如果Node_NL不为None,Node_Now = Node_rL,转到2
2-2. 如果Node_NL为空,则转到3
3. 对于Node_Now(同上)的右子树进行如下判断:
3-1.如果Node_NR不为None, Node_Now = Node_rL,转到2
3-2.如果Node_NR为空,则Node_Now标记为None,置Node_Now = Node_P


写到这里发现上面的DFS写错了。

DFS应当是和数据结构(栈)结合起来的,而BFS是和数据结构(队列)结合起来的,这么一想,其实用BFS要简单一些(我对队列更熟悉一些)。有些东西太久不用就有些秀逗啦。虽然这道题只是最简单的之一,但还是提供了很大帮助。


重写DFS

Update

1. stack 初始为空列表;
2. 如果root不为None,(root)入栈
3. 循环体开始,当stack不为空时,执行:
        3.1. 当前指针node_now = stack.pop()
        3.2. 如果node_now -> rightchild不为空,则rightchild入栈
        3.3. 如果node_now -> leftchild不为空,则leftchild入栈
        3.4. 如果均为空,node_now则为叶子节点,continue
4. 算法结束

想了好久,才从(如果左节点存在,继续往左走,否则回退)想出来DFS的算法。因为栈的逆序性质,所以按照某个方向(如左子树)递归查找,需要将另一个方向的结点先行入栈。

对于这道题来说,在入栈时同时对depth入栈,就可以得到结果了。

BFS

1. queue 初始为空队列;
2. 如果root不为None,(root)入队列
3. 循环体开始,当queue不为空时,执行:
        3.1. 当前指针node_now = queue.pop()
        3.2. 如果node_now -> rightchild不为空,则rightchild入队列
        3.3. 如果node_now -> leftchild不为空,则leftchild入队列
        3.4. 如果均为空,node_now则为叶子节点,continue
4. 算法结束

可以看出来BFS和DFS的唯一区别在于存储结构的不同,因此,如果利用python的列表(实际上是一种栈)模拟队列操作就可以实现BFS了。

我的解法

基于DFS实现的解法。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        stack = []
        stepdepth = 1 # the length of stack
        maxDepth = 0
        node_now = root
        if root is not None:
            stack.append((root,stepdepth))
        #clear result = []
        while stack != [] :
            node_now, stepdepth = stack.pop()
            stepdepth += 1
            # Run into right child tree
            if node_now.right is not None:
                stack.append((node_now.right, stepdepth))
            # Run into left child tree
            if node_now.left is not None:
                stack.append((node_now.left, stepdepth))
            # Stack pop out the 
            if node_now.right is None and node_now.left is None:
                stepdepth -= 1
                maxDepth = max(maxDepth, stepdepth)
            #clear result.append((node_now.val, stepdepth))
        return maxDepth#clear ,result

#####################
# 实现BFS,
# 只需要将stack.pop()修改,
# stack.pop() -> stack[0];stack = stack[1:];
# 

中间result是调试的时候用到的。
如果在while循环体的条件,使用len函数判断stack是否为空,会慢4ms(68ms),使用!= 判断(64ms)。
由于BFS不是原生的实现,速度会慢一大截(72ms)。

关于二叉树测试数据

其实在custom test的hint中有写,
leetcode的二叉树测试数据是列表形式的。
即[11, 12,13, 14,15,16,17, 18,19]实际上描述了一个

depth_1 11 -> (12, 13)
depth_2 12 -> (14, 15)
depth_2 13 -> (16, 17)
depth_3 14 -> (18, 19)
depth_3 15 -> (nu, nu)
depth_3 16 -> (nu, nu)
depth_3 17 -> (nu, nu)

的二叉树,nu即是None。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值