深度优先搜索DFS | 广度优先搜索BFS --牛客-剑指offer系列题解:二叉树的深度、平衡二叉树(以及力扣中的一个变形:二叉树的最小深度)

记录刷题的过程。牛客和力扣中都有相关题目,这里以牛客的题目描述为主。该系列默认采用python语言。

1、二叉树的深度

1、问题描述:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

2、数据结构:

二叉树

3、题解:
方法1:深度优先搜索,要想得到深度,就得知道左、右子树的深度,然后让左、右子树中最大的深度+1就得到根节点的深度。用递归

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        #DFS后序遍历
        if not pRoot:
            return 0
        return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right)) + 1 

方法2:
广度优先搜索。我们定义一个记号,当遍历完一层时,就加1,遍历到最后一层时,也就找到了最大深度。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        #BFS
        if not pRoot:
            return 0
        import collections
        queue,res = collections.deque([pRoot]),0
        while queue:
            size = len(queue)
            for _ in range(size):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res += 1
        return res

4、复杂度分析:
方法1和方法2都是
时间复杂度:O(N)

空间复杂度:O(N)

2、平衡二叉树

1、问题描述:
在这里插入图片描述
在这里插入图片描述
2、数据结构:
二叉树

3、题解:
此题DFS加上剪枝。如果左右两个子树的深度差大于1,直接返回-1;如果不大于1,就得到最大深度(也就是上一题的思路),在算每个子树的深度时,都要判断深度差是不是超过了1.最后把其封装成一个函数,调用函数,判断返回值是否不等于-1,如果不等于-1,说明满足平衡二叉树。

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

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def recur(root):
            if not root:
                return 0
            left = recur(root.left)
            if left == -1:
                return -1
            right = recur(root.right)
            if right == -1:
                return -1
            return max(left, right) + 1 if abs(left - right) < 2 else -1
        return recur(root) != -1

4、复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N)

3、二叉树的最小深度

1、问题描述:
在这里插入图片描述
2、数据结构:
二叉树

3、题解:
方法1:DFS
其实一开始是用第一个题的思路,直接把max改成min,但是没有通过。之后思考了一下,当左、右节点,有一个不存在时,返回的是根节点的深度,但其实应该返回的是存在的子树的深度。如下图:
在这里插入图片描述
如果用刚刚的思路,那么深度为根节点5的深度,也就是1,但其实最小深度应该为3.
所以在递归调用时,要加一个判断,如果遇到刚刚的情况,就返回存在的那个子树的深度+1就可以。

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

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        # DFS
        if not root:
            return 0
        left = self.minDepth(root.left)
        right = self.minDepth(root.right)
        if not root.left or not root.right:  # 处理特殊情况,左、右节点有一个不存在
            return left + 1 if right == 0 else right + 1 #返回存在的那个子树+1
        return min(left, right) + 1

方法2:BFS
比二叉树的最大深度在BFS每层时多了一个判断:如果是叶子节点就返回depth。

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        #BFS
        if not root: return 0
        queue = collections.deque()
        queue.append(root)
        depth = 0
        while queue:
            depth += 1
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if not node.left and not node.right:
                    return depth
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return -1

4、复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值