Skip to content

一、问题描述

给定一个二叉树的根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

示例

输入:

    1
   / \
  2   3
 /   / \
4   5   6
   /
  7

输出: 7

解释:

在这个二叉树中,最左下角的值是7,因为它是最后一行中最左边的值。

二、方案一:广度优先搜索(BFS)

1、思路

使用广度优先搜索(BFS)遍历树,每一层从左到右遍历,这样最后一个遍历到的节点就是最左下角的值。

2、代码实现

go
func findBottomLeftValue(root *TreeNode) int {
    queue := []*TreeNode{root}
    var result int
    for len(queue) > 0 {
        levelSize := len(queue)
        for i := 0; i < levelSize; i++ {
            node := queue[0]
            queue = queue[1:]
            if i == 0 {
                result = node.Val // 每层的第一个节点
            }
            if node.Left != nil {
                queue = append(queue, node.Left)
            }
            if node.Right != nil {
                queue = append(queue, node.Right)
            }
        }
    }
    return result
}

3、复杂度分析

  • 时间复杂度:O(n),其中n是树中节点的数量。每个节点都会被访问一次。
  • 空间复杂度:O(m),其中m是树的最大宽度。在最坏的情况下,树是一个完全二叉树,队列中最多会有m个节点。

三、方案二:深度优先搜索(DFS)

1、思路

使用深度优先搜索(DFS)遍历树,记录当前的最大深度和对应的最左边的值。在遍历过程中,如果当前节点的深度大于已记录的最大深度,则更新最大深度和对应的值。

2、代码实现

go
var maxDepth int
var leftMostValue int
func findBottomLeftValue(root *TreeNode) int {
    maxDepth = -1
    leftMostValue = 0
    dfs(root, 0)
    return leftMostValue
}
func dfs(node *TreeNode, depth int) {
    if node == nil {
        return
    }
    if depth > maxDepth {
        maxDepth = depth
        leftMostValue = node.Val
    }
    dfs(node.Left, depth+1)
    dfs(node.Right, depth+1)
}

3、复杂度分析

  • 时间复杂度:O(n),其中n是树中节点的数量。每个节点都会被访问一次。
  • 空间复杂度:O(h),其中h是树的高度。在最坏的情况下,树是一个倾斜的树,递归栈的深度为h。

四、总结

两种方案都可以解决问题,BFS更直观,而 DFS 则需要额外的变量来记录最大深度和对应的最左边的值。在大多数情况下,BFS是更常用的方法,因为它更易于理解和实现。

木川工作室 (微信:mcmc2024)