力扣每日一题0624-在每个树行中找最大值

96 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

示例1:

image.png

输入:root = [1,3,2,5,3,null,9]
输出:[1,3,9]

示例2:

输入:root = [1,2,3]
输出:[1,3]

深度优先搜索

我们用树的「先序遍历」来进行「深度优先搜索」处理,并用 curHeight\textit{curHeight} 来标记遍历到的当前节点的高度。当遍历到 curHeight\textit{curHeight} 高度的节点就判断是否更新该层节点的最大值。

var largestValues = function(root) {
    if (!root) {
        return [];
    }
    const res = [];
    const dfs = (res, root, curHeight) => {
        if (curHeight === res.length) {
            res.push(root.val);
        } else {
            res.splice(curHeight, 1, Math.max(res[curHeight], root.val));
        }
        if (root.left) {
            dfs(res, root.left, curHeight + 1);
        }
        if (root.right) {
            dfs(res, root.right, curHeight + 1);
        }
    }
    dfs(res, root, 0);
    return res;
};

复杂度分析

  • 时间复杂度: O(n)O(n),其中 nn 为二叉树节点个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。
  • 空间复杂度:O(height)O(\textit{height})。其中 height\textit{height} 表示二叉树的高度。递归函数需要栈空间,而栈空间取决于递归的深度,因此空间复杂度等价于二叉树的高度。

广度优先搜索

我们也可以用「广度优先搜索」的方法来解决这道题目。「广度优先搜索」中的队列里存放的是「当前层的所有节点」。每次拓展下一层的时候,不同于「广度优先搜索」的每次只从队列里拿出一个节点,我们把当前队列中的全部节点拿出来进行拓展,这样能保证每次拓展完的时候队列里存放的是下一层的所有节点,即我们是一层一层地进行拓展,然后每一层我们用 maxVal\textit{maxVal} 来标记该层节点的最大值。当该层全部节点都处理完后,maxVal\textit{maxVal} 就是该层全部节点中的最大值。

var largestValues = function(root) {
    if (!root) {
        return [];
    }
    const res = [];
    const queue = [root];
    while (queue.length) {
        let len = queue.length;
        let maxVal = -Number.MAX_VALUE;
        while (len > 0) {
            len--;
            const t = queue.shift();
            maxVal = Math.max(maxVal, t.val);
            if (t.left) {
                queue.push(t.left);
            }
            if (t.right) {
                queue.push(t.right);
            }
        }
        res.push(maxVal);
    }
    return res;
};

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 为二叉树节点个数,每一个节点仅会进出队列一次。
  • 空间复杂度: O(n)O(n),存储二叉树节点的空间开销。