图解精选 TOP 面试题 002 | LeetCode 104. 二叉树的最大深度

该系列题目取自 LeetCode 精选 TOP 面试题列表:https://leetcode-cn.com/problemset/top/

题目描述

原题链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明:叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7]

    3
   /   9  20
    /     15   7

返回它的最大深度 3 。

解题思路

题目要求求出二叉树的最大深度,我们知道,每个节点的深度与它左右子树的深度有关,且等于其左右子树最大深度值加上 1,可以写作:

maxDepth(root) = max(maxDepth(root.left), maxDepth(root.right)) + 1

[3,9,20,null,null,15,7] 为例,根节点 3 的深度取决于它左右子树的深度:

因其左右子树深度尚不可知,我们需要对其一一求解。

先来看左子树,即以 4 为根节点的子树,因为它没有左右子节点,所以深度为 1:

再来看以 20 为根节点的右子树,同理,它的深度也取决于左右子树的深度:

它的左子节点 15 与右子节点 7 的情况与上述节点 4 相同,左右子节点均为空,所以这两个节点的深度也是 1。由此我们可以得出节点 20 的深度为 2,推导过程如下:

max(左子树最大深度, 右子树最大深度) + 1
=
max(1, 1) + 1
=
1 + 1
=
2

这样一来,我们知道了所有子节点的深度,各节点深度如下:

由此可得根节点 3 的深度为:

max(左子树最大深度, 右子树最大深度) + 1
=
max(1, 2) + 1
=
2 + 1
=
3

上述推导过程整体如下:

maxDepth(3-root)
=
max(maxDepth(4-sub), maxDepth(20-sub)) + 1
=
max(1, max(maxDepth(15-sub), maxDepth(7-sub)) + 1) + 1
=
max(1, maxDepth(1, 1) + 1) + 1
=
max(1, 2) + 1
=
2 + 1
=
3

在推导过程中我们看到 maxDepth() 函数频繁出现,即我们在频繁地求取某节点的最大深度。由此可见,「求节点的最大深度」是该题的子问题,该题最直观的解答方式是用递归求解。

递归设计

在递归算法中,递归函数的设计非常重要,首先我们要先明确该函数的作用,然后再确定何时结束与何时调用该函数

明确函数作用

该函数的作用用一句话概括就是:计算节点的最大深度

  • 函数输入:确定的节点
  • 函数输出:该节点的最大深度

何时结束

当输入的节点为空节点时,我们无需继续计算其子树的深度,此时可以直接结束递归函数,并返回空节点的深度为 0。

何时调用

当输入节点为非空节点时,该节点的深度取决于其左右子树的深度,即:

maxDepth(root) = max(maxDepth(root.left), maxDepth(root.right)) + 1

此时需要进行函数的递归调用。

具体实现

Python

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

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if root is None:
            return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

Golang

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
}

func max(a int, b int) int {
    if a > b {
        return a
    }
    return b
}

复杂度

假设节点的数量为 n。

时间复杂度

因为每个节点都需要被访问一次,因此时间复杂度为 O(n)

空间复杂度

考虑到递归使用调用栈(call stack)的情况。

  • 最坏情况:树完全不平衡。例如每个节点都只有右节点,此时将递归 n 次,需要保持调用栈的存储为 O(n)
  • 最好情况:树完全平衡。即树的高度为 log(n),此时空间复杂度为 O(log(n))

总结一下

与树相关的题目常用递归来解,对于递归而言,我们需要明确:

  1. 递归函数的用途
  2. 递归函数的结束条件
  3. 递归函数自身调用的时机

除此之外,在计算空间复杂度时,我们也要考虑到递归时调用栈的情况。

当然了,这道题还可以用迭代法来做,由于篇幅有限,就不在本篇叙述了。大家可以想想要怎么用迭代法解答本题,我们下次再来细说~


往期回顾

推荐阅读


??

如果你觉得文章写得不错,请帮我两个小忙:

  1. 点赞并关注我,让这篇文章被更多人看到
  2. 关注公众号「编程拯救世界」,公众号专注于编程基础服务端研发,你将第一时间获得新文章的推送~

原创不易,多多鼓励~谢谢大家!

原文地址:https://www.cnblogs.com/jalan/p/11965300.html

时间: 2024-08-29 20:18:46

图解精选 TOP 面试题 002 | LeetCode 104. 二叉树的最大深度的相关文章

图解精选 TOP 面试题 001 | LeetCode 237. 删除链表中的节点

题目描述 原题链接 LeetCode 237. 删除链表中的节点:https://leetcode-cn.com/problems/delete-node-in-a-linked-list 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点. 现有一个链表 head =?[4,5,1,9],它可以表示为: 示例 1: 输入: head = [4,5,1,9], node = 5 输出: [4,1,9] 解释: 给定你链表中值为 ?5? 的第二个节点,那么在调

Leetcode 104. 二叉树的最大深度

题目链接 https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/description/ 题目描述 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], 3 / 9 20 / 15 7 返回它的最大深度 3 . 题解 深度遍历,使用递归的解法. 代码 /** * Definitio

Leetcode题目104.二叉树的最大深度(DFS+BFS简单)

题目描述: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], 3 / 9 20 / 15 7 返回它的最大深度 3 . 思路分析:递归(二叉树最大深度,等于左右子树的最大深度+1) 代码实现: 一.深度优先比遍历(DFS) /** * Definition for a binary tree node. * public class TreeNo

124. 二叉树中的最大路径和/104. 二叉树的最大深度

我最想刷的递归又来啦,待我先去好好研究一下. 据说T124是T104的进阶,所以先去刷下104 104: 顶层: 即在真正的root节点上,我要返回的是一个数字,而且要比我的左右节点返回的深度大1 def maxDepth(self,root): return max(maxDepth(root.left)+1,maxDepth(root.right)+1) 底层:当遇到叶子节点时候,深度为1,其左右的None 深度为0,所以basecase 应该是叶子节点的再下一层,不要搞错了. if not

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], 3 / 9 20 / 15 7 返回它的最大深度 3 . 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right;

Java笔试面试题002

  Java笔试面试题002 1.struts2中,Action通过什么方式获得用户从页面输入的数据,又是通过什么方式把其自身的数据传给视图的? 解答: 1)可以直接通过与表单元素相同名称的数据成员(需要存在符合命名规范set和get方法)获取页面表单数据. 2)会把处理好的数据成员放入值栈中,到页面可以使用struts2标签取值就可以了. 2.常用的设计模式有哪些?说明工厂模式. 解答:Java中的23种设计模式: Factory(工厂模式), Builder(建造模式),Factory Me

[leetcode]重建二叉树(先序和终须) 中序遍和后续

分割后长度相等,就是参数麻烦,p,先序的起始点, ib,ie 终须的结束和开始. 1 /** 2 * Definition for binary tree 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 public TreeNode bu

[LeetCode系列] 二叉树最大深度求解问题(C++递归解法)

问: 给定二叉树, 如何计算二叉树最大深度? 算法描述如下: 如果当前节点为空, 返回0(代表此节点下方最大节点数为0) 如果当前节点不为空, 返回(其左子树和右子树下方最大节点数中的最大值+1) 上述算法的精髓在于递归调用中的终止条件. 代码如下: 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNod

LeetCode:二叉树相关应用

LeetCode:二叉树相关应用 基础知识 617.归并两个二叉树 题目 Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new binary tree. The merge ru