Java&C++题解与拓展——leetcode508.出现次数最多得子树元素和【么的新知识】

这篇博客介绍了如何利用深度优先搜索(DFS)算法解决寻找树中出现频率最高的子树元素和的问题。作者分别用Java、C++和Rust实现了该算法,并分析了时间复杂度和空间复杂度均为O(n)。在实现过程中,作者遇到了Java返回值处理和Rust的borrow、clone、unwrap操作的挑战。最后,博客总结了在处理树结构问题时DFS的常见应用。

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

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

题目要求

在这里插入图片描述

思路:DFS

  • 遍历整棵树,计算每一个节点的子树元素和,放入哈希表(去重+计数),同时记得维护一个最大值用以构造答案。

【论一道DFS模拟题怎么编出一段文字叙述的题解】

Java

class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    int maxv = 0;
    int DFS(TreeNode root) {
        // 遍历计算子树元素和
        if (root == null)
            return 0;
        int cur = root.val + DFS(root.left) + DFS(root.right);
        map.put(cur, map.getOrDefault(cur, 0) + 1);
        maxv = Math.max(map.get(cur), maxv); // 维护最大值
        return cur;
    }
    public int[] findFrequentTreeSum(TreeNode root) {
        DFS(root);
        // 构造答案
        List<Integer> list = new ArrayList<>();
        for (int vlu : map.keySet()) {
            if (map.get(vlu) == maxv)
                list.add(vlu);
        }
        int n = list.size();
        int[] res = new int[n];
        for (int i = 0; i < n; i++)
            res[i] = list.get(i);
        return res;
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

C++

class Solution {
    unordered_map<int, int> map;
    int maxv = 0;
public:
    int DFS(TreeNode *root) {
        // 遍历计算子树元素和
        if (root == nullptr)
            return 0;
        int cur = root->val + DFS(root->left) + DFS(root->right);
        map[cur] = map[cur] + 1;
        maxv = max(map[cur], maxv); // 维护最大值
        return cur;
    }
    vector<int> findFrequentTreeSum(TreeNode* root) {
        DFS(root);
        // 构造答案
        vector<int> res;
        for (auto &[vlu, cnt] : map) {
            if (cnt == maxv)
                res.push_back(vlu);
        }
        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::HashMap;
impl Solution {
    fn DFS(root: Rc<RefCell<TreeNode>>, map: &mut HashMap<i32, usize>) -> i32 {
        // 遍历计算子树元素和
        let cur = if root.borrow().left.is_none() && root.borrow().right.is_none() {
            root.borrow().val
        } else {
            let mut cur = root.borrow().val;
            if root.borrow().left.is_some() {
                let rl = root.borrow().left.clone().unwrap();
                cur += Solution::DFS(rl, map);
            }
            if root.borrow().right.is_some() {
                let rr = root.borrow().right.clone().unwrap();
                cur += Solution::DFS(rr, map);
            }
            cur
        };
        map.insert(cur, *map.get(&cur).unwrap_or(&0) + 1);
        cur
    }
    pub fn find_frequent_tree_sum(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
        let mut map = HashMap::new();
        Solution::DFS(root.unwrap(), &mut map);
		// 构造答案
        let mut maxv = 0;
        let mut res = vec![];
        map.iter().for_each(|(&vlu, &cnt)| {
            if cnt > maxv {
                maxv = cnt;
                res = vec![vlu]
            }
            else if cnt == maxv {
                res.push(vlu);
            }
        });
        res
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

总结

看到树了不来个DFS都说不过去,遍历顺便计算子树元素和,这题没想到卡在了Java的返回值,还要绕一步再构造数组。

又在rust的borrowcloneunwrap各种里绕了半天。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值