Java&C++题解与拓展——leetcode515.在每个树行中找最大值【么的新知识】

本文详细解析了如何使用BFS广度优先搜索和DFS深度优先搜索算法在二叉树中找到每层的最大值,包括Java、C++和Rust三种编程语言的实现,同时对比了两种方法的时间和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每日一题做题记录,参考官方和三叶的题解

题目要求

在这里插入图片描述

思路一:BFS

  • 既然找每个层,那就直接BFS然后遍历每一层时维护一个最大值加入答案。

Java

class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null)
            return res;
        Deque<TreeNode> que = new ArrayDeque<>();
        que.addLast(root);
        while (!que.isEmpty()) {
            int ql = que.size(), maxv = que.peek().val;
            while (ql-- > 0) { // 遍历当前层
                TreeNode node = que.pollFirst();
                maxv = Math.max(maxv, node.val); // 维护最大值
                if (node.left != null)
                    que.addLast(node.left);
                if (node.right != null)
                    que.addLast(node.right);
            }
            res.add(maxv);
        }
        return res;
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

C++

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> res;
        if (root == nullptr)
            return res;
        queue<TreeNode *> que;
        que.push(root);
        while (!que.empty()) {
            int ql = que.size(), maxv = que.front()->val;
            while (ql-- > 0) { // 遍历当前层
                TreeNode* node = que.front();
                que.pop();
                maxv = max(maxv, node->val); // 维护最大值
                if (node->left != nullptr)
                    que.push(node->left);
                if (node->right != nullptr)
                    que.push(node->right);
            }
            res.emplace_back(maxv);
        }
        return res;
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

Rust

use std::rc::Rc;
use std::cell::RefCell;
use std::collections::VecDeque;
impl Solution {
    pub fn largest_values(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
        let mut res = vec![];
        let mut que = VecDeque::new();
        if let Some(node) = root {
            que.push_back(node);
        }
        else {
            return res;
        }
        while !que.is_empty() {
            let mut maxv = i32::MIN;
            for _ in 0..que.len() { // 遍历当前层
                let cur = que.pop_front().unwrap();
                if let Some(left) = cur.borrow_mut().left.take() {
                    que.push_back(left);
                }
                if let Some(right) = cur.borrow_mut().right.take() {
                    que.push_back(right);
                }
                if cur.borrow().val > maxv { // 维护最大值
                    maxv = cur.borrow().val;
                }
            }
            res.push(maxv);
        }
        res
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

思路二:DFS

【都写树了,不得想个办法给DFS也搞了,一家人就是要整整齐齐】

  • 需要定义一些全局变量,记录一下最大深度和每一层的(当前的)最大值:
    • 其中每层最大值用哈希表维护,最后根据这个表构造答案。

Java

class Solution {
    int maxd = 0; // 最大深度
    Map<Integer, Integer> maxv = new HashMap<>(); // (depth, maxv)
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        DFS(root, 1);
        for (int i = 1; i <= maxd; i++)
            res.add(maxv.get(i));
        return res;
    }

    void DFS(TreeNode node, int curd) {
        if (node == null)
            return ;
        maxd = Math.max(maxd, curd);
        maxv.put(curd, Math.max(maxv.getOrDefault(curd, Integer.MIN_VALUE), node.val));
        DFS(node.left, curd + 1);
        DFS(node.right, curd + 1);
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

C++

【直接把getOrDefault直接粗暴改了赋值,然后报错了……还是要细致一点注意判空】

class Solution {
public:
    int maxd = 0; // 最大深度
    unordered_map<int, int> maxv; // (depth, maxv)
    vector<int> largestValues(TreeNode* root) {
        vector<int> res;
        DFS(root, 1);
        for (int i = 1; i <= maxd; i++)
            res.emplace_back(maxv[i]);
        return res;
    }
    void DFS(TreeNode* node, int curd) {
        if (!node)
            return ;
        maxd = max(maxd, curd);
        if (maxv.count(curd)) //getOrDefault
            maxv[curd] = max(maxv[curd], node->val);
        else
            maxv[curd] = node->val;
        DFS(node->left, curd + 1);
        DFS(node->right, curd + 1);
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

Rust

【嘤嘤嘤怎么人家写起来那么简单,自己就捣鼓不清楚】

use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
    pub fn largest_values(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
        fn DFS(root: Option<Rc<RefCell<TreeNode>>>, maxv: &mut Vec<i32>, curd: i32) {
            if let Some(node) = root {
                if curd >= maxv.len() as i32 {
                    maxv.push(node.borrow().val);
                }
                else {
                    maxv[curd as usize] = maxv[curd as usize].max(node.borrow().val);
                }
                DFS(node.borrow_mut().left.take(), maxv, curd + 1);
                DFS(node.borrow_mut().right.take(), maxv, curd + 1);
            }
        }
        let mut res = Vec::new();
        DFS(root, &mut res, 0);
        res
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

总结

快乐二叉树的快乐遍历,看到二叉树的中等就知道今天可以光速解决了,我永远热爱树的搜索。


欢迎指正与讨论!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值