IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 力扣 2385. 感染二叉树需要的总时间 -> 正文阅读

[数据结构与算法]力扣 2385. 感染二叉树需要的总时间

题目来源:https://leetcode.cn/problems/amount-of-time-for-binary-tree-to-be-infected/

大致题意:
给一个二叉树和一个节点,假设该节点每单位时间可以感染与其相邻的节点,被感染的节点之后也会感染相邻节点,求整颗二叉树被感染需要的时间。
相邻节点是指某个节点的子节点和父节点

思路

比较简单的方法是:

  • 遍历二叉树,存每个节点的父节点,构建一张图,然后使用给定节点作为源点,遍历求整张图其他节点距离源点的最短距离即可

但是该方法需要额外的空间来存储父节点,可以分析该问题得到该二叉树被感染的时间的计算方式:

  1. 若当前节点是目标节点,那么以该节点为根节点的子树被感染需要的时间为 max(左子树被感染的时间, 右子树被感染的时间) + 1。这里子树被感染的时间即为子树的深度
  2. 若目标节点在当前节点左子树,那么以该节点为根节点的右子树被感染需要的时间为 目标节点到当前节点的时间 + 右子树被感染的时间 + 1
  3. 同理,若目标节点在当前节点右子树,那么以该节点为根节点的左子树被感染需要的时间为 目标节点到当前节点的时间 + 左子树被感染的时间 + 1
  4. 还有一种情况,就是目标节点不在当前子树中,只是和当前子树有公共祖先,那么如何求当前子树被感染时间?其实对于这种情况,其子树被感染时间为 目标节点和当前节点之间的距离 + 当前子树的深度,而 目标节点和当前节点之间的距离 即为 当前节点和目标节点最近公共祖先与当前节点的距离 + 最近公共祖先与目标节点的距离,于是子树被感染的时间即为 最近公共祖先与当前节点的距离 + 最近公共祖先与目标节点的距离 + 当前子树的深度,同时 最近公共祖先与当前节点的距离 + 当前子树的深度 即为 公共祖先子树的深度,而这个值在遍历到公共祖先节点的时候已经算过了

在未找到目标节点时,可以认为某个节点感染其子节点的时间即为距离

于是可以通过 bfs 遍历求得上述所有感染时间的最大值即为答案,具体搜索时可以使用一个标志位存下目标节点所在层,同时每次遍历是标记当前节点所在层,这样当找到目标节点时,即可通过层数之间的差求得目标节点和祖先节点之间的感染时间。对于目标节点不在当前节点子树的情况,因为有标志位判断的情况存在,若此时目标节点已找到,相等于目标节点在左子树的情况(但是当前结果不会对答案有贡献,只是免去了特殊处理),否则不做特殊处理。

具体看代码:

class Solution {
    int ans;	// 二叉树被感染的时间
    int startDepth;	// 目标节点所在层
    int start;	// 目标节点值
    public int amountOfTime(TreeNode root, int start) {
        ans = 0;
        startDepth = -1;	// 初始化为 -1,表示未找到目标节点
        this.start = start;
        dfs(root, 0);
        return ans;
    }

    public int dfs(TreeNode node, int depth) {
        if (node == null) {
            return 0;
        }
        // 当前节点左子树的最大深度
        int l = dfs(node.left, depth + 1);
        // 如果此时目标节点已找到,说明目标节点在左子树中
        boolean inLeft = startDepth != -1;
        // 当前节点右子树的最大深度
        int r = dfs(node.right, depth + 1);
        // 如果此时目标节点找到,说明目标节点在右子树中
        boolean inRight = !inLeft && startDepth != -1;
        // 若当前节点为目标节点,更新目标节点深度和答案
        if (node.val == start) {
            startDepth = depth;
            ans = Math.max(Math.max(l, r), ans);
        } else if (inLeft) {	// 在左子树中,更新答案
            ans = Math.max(startDepth - depth + r, ans);
        } else if (inRight) {	// 在右子树中,更新答案
            ans = Math.max(startDepth - depth + l, ans);
        }
        return Math.max(l, r) + 1;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 01:12:58  更:2022-09-30 01:17:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 20:10:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码