高频算法面试题(三十五)- 二叉树的最大深度

「这是我参与11月更文挑战的第 20 天,活动详情查看:2021最后一次更文挑战

刷算法题,从来不是为了记题,而是练习把实际的问题抽象成具体的数据结构或算法模型,然后利用对应的数据结构或算法模型来进行解题。个人觉得,带着这种思维刷题,不仅能解决面试问题,也能更多的学会在日常工作中思考,如何将实际的场景抽象成相应的算法模型,从而提高代码的质量和性能

二叉树的最大深度

题目来源LeetCode-104.二叉树的最大深度

题目描述

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

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

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

示例

示例 1

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

		3
   / \
  9  20
    /  \
   15   7
复制代码

返回它的最大深度 3

解题

如果你看过我前边的一篇求二叉树的右视图的文章,这道题的思路跟那个差不多,但这个更加的简单

解法一:深度优先搜索

思路

求最大深度,我们最容易想到的其实就是层序遍历。但是你会发现用层序遍历,并不容易记录当前是哪一层。因此,我们可以考虑用深度优先搜索

深度优先搜索:随意选择一个岔路口来走,走着走着发现走不通的时候,就回退到上一个岔路口,重新选择一条路继续走,直到走完所有的情况

假设我们知道了一棵二叉树的左右子树的深度分别是l和r,那么这颗二叉树的最大深度就是max(l, r)+1

而左右子树的最大深度,可以使用相同的方法来计算,那现在递归公式就有了

max(maxDepth(root.Left), maxDepth(root.Right))
复制代码

代码

func maxDepth(root *TreeNode) int {
	if root == nil {
		return 0
	}

	return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
}

func max(x, y int) int {
	if x > y {
		return x
	}

	return y
}
复制代码

解法二:广度优先搜索

思路

广度优先搜索:是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后是次近的,依次往外搜索

广度优先搜索可以借助队列来实现,但是解本题的时候,需要做些变化

  • 队列里边存的是当前层的所有结点
  • 每次遍历下一层的时候,不同于广度优先搜索的每次只从队列里拿出一个节点,我们需要将队列里的所有节点都拿出来进行遍历,这样能保证每次拓展完的时候队列里存放的是当前层的所有节点,即我们是一层一层地进行遍历
  • 每向下遍历一层,深度就+1

代码一看就明白

代码

//广度优先搜索实现
func maxDepth2(root *TreeNode) int {
	if root == nil {
		return 0
	}

	widthQueue := []*TreeNode{root}
	depth := 0

	for len(widthQueue) != 0 {
		count := len(widthQueue)
		for count > 0 {
			node := widthQueue[0]
			if len(widthQueue) > 1 {
				widthQueue = widthQueue[1:]
			} else {
				widthQueue = []*TreeNode{}
			}
			if node.Left != nil {
				widthQueue = append(widthQueue, node.Left)
			}
			if node.Right != nil {
				widthQueue = append(widthQueue, node.Right)
			}

			count--
		}
		depth++
	}

	return depth
}
复制代码

猜你喜欢

转载自juejin.im/post/7032557538939764744
今日推荐