leetcode
leetcode 2951 ~ 3000
找树左下角的值

找树左下角的值

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 27 ms, 内存: 17.9 MB


/*
题目思路:
1. 使用深度优先搜索(DFS)来遍历二叉树。
2. 记录每一层最左边节点的值。
3. 使用Java Streams来简化代码。
*/

// Definition for a binary tree node.
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

import java.util.*;
import java.util.stream.*;

public class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Map<Integer, Integer> leftmostValues = new HashMap<>();
        findBottomLeftValue(root, 0, leftmostValues);
        return leftmostValues.entrySet().stream()
                              .max(Map.Entry.comparingByKey())
                              .get()
                              .getValue();
    }

    private void findBottomLeftValue(TreeNode node, int depth, Map<Integer, Integer> leftmostValues) {
        if (node == null) return;
        leftmostValues.putIfAbsent(depth, node.val);
        findBottomLeftValue(node.left, depth + 1, leftmostValues);
        findBottomLeftValue(node.right, depth + 1, leftmostValues);
    }
}

解释

方法:

此题解采用深度优先搜索(DFS)来寻找二叉树最底层最左边的节点值。使用两个非局部变量:left来记录当前找到的最左值,curH来记录当前的最大深度。DFS从根节点开始,对每个节点检查其深度是否超过了当前已知的最大深度curH。如果是,更新curH和left。DFS首先访问左子节点,确保最左的节点会被优先记录。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在DFS遍历中,先访问左子节点再访问右子节点对于解题特别重要?
在这个问题中,目标是找到二叉树最底层的最左边的节点值。通过先访问左子节点再访问右子节点,确保了如果存在同一深度的多个节点,最左边的节点会首先被访问并记录。这是因为DFS会深入到最左边的路径直到无法继续为止,从而第一个达到最深层的节点肯定是最左边的节点。这样的访问顺序直接支持了题目的要求,即找到最底层最左边的值。
🦆
在DFS递归函数中,如果当前节点的高度与已知的最大深度相同,为什么不更新最左值?
在DFS递归函数中,当当前节点的高度等于已知的最大深度时,不更新最左值是因为我们只需要在达到一个新的更深的层级时更新最左值。如果当前节点的高度仅等于已有的最大深度,说明我们已经在该深度层级访问过至少一个节点,且最左的节点已经被记录。此时更新最左值将导致不必要的覆盖,从而不再保持最左的特性。
🦆
解题中提到的非局部变量left和curH在递归中是如何更新并保持其最新值的?
在递归函数中,left和curH被定义为nonlocal变量,这意味着它们不是局部变量也不是全局变量,而是引用了外层作用域中的相同名称的变量。在递归过程中,每当找到一个更深层级的节点时,这两个变量都会被更新。由于它们是nonlocal变量,它们的改变会影响到所有递归调用中的同名变量。因此,无论递归在哪一层执行,left和curH总是被保持为最新更新的状态,确保了整个递归过程中这两个变量的一致性和准确性。

相关问题