稀碎从零算法笔记Day59-LeetCode: 感染二叉树需要的总时间

题型:树、图、BFS、DFS

链接:2385. 感染二叉树需要的总时间 - 力扣(LeetCode)

来源:LeetCode

题目描述

给你一棵二叉树的根节点 root ,二叉树中节点的值 互不相同 。另给你一个整数 start 。在第 0 分钟,感染 将会从值为 start 的节点开始爆发。

每分钟,如果节点满足以下全部条件,就会被感染:

  • 节点此前还没有感染。
  • 节点与一个已感染节点相邻。

返回感染整棵树需要的分钟数*。*

题目样例

示例 1:

复制代码
输入:root = [1,5,3,null,4,10,6,9,2], start = 3
输出:4
解释:节点按以下过程被感染:
- 第 0 分钟:节点 3
- 第 1 分钟:节点 1、10、6
- 第 2 分钟:节点5
- 第 3 分钟:节点 4
- 第 4 分钟:节点 9 和 2
感染整棵树需要 4 分钟,所以返回 4 。

示例 2:

复制代码
输入:root = [1], start = 1
输出:0
解释:第 0 分钟,树中唯一一个节点处于感染状态,返回 0 。

提示:

  • 树中节点的数目在范围 [1, 105]
  • 1 <= Node.val <= 105
  • 每个节点的值 互不相同
  • 树中必定存在值为 start 的节点

题目思路

乍一看能感觉出来是层序遍历(广度优先遍历),或者说求树的最大深度?

但是他不是树的遍历方式------因为start不一定是root结点

如果是一个图进行,那问题也会简单许多------直接BFS拓扑排序就行,但这是个树,所以可以考虑先把 树转化为图 然后进行BFS

那问题就可以转化为 ①将树转化为图 ② BFS遍历图

将树转化为图可以DFS遍历一次:图的数据结构可以用 vector<int> 来存相连的点的val

转化为图后可以进行从 start 开始的 BFS ---- 用queue来存拓扑排序的点的 【相连的点】 。遍历完一次后就可以将【相连的点】添加到 queue 中。

考虑到一个点可能被多个点相连进而可能被访问多次,可以用 visit 数组来存一下是否被访问过

C++代码

cpp 复制代码
class Solution {
public:
    int amountOfTime(TreeNode* root, int start) {
        // int存time vector<int> 存孩子/父节点
        unordered_map<int,vector<int>>graph;
        // lambda定义dfs
        function<void(TreeNode *)>dfs = [&](TreeNode * node){
            //将左右孩子整合为child
            for(TreeNode *child : vector<TreeNode *> {node ->left,node -> right}){
                if(child != nullptr){
                    // 将孩子结点添加到数组中 ------ 数组存相连的点
                    graph[node -> val].push_back(child -> val);
                    // 将父亲结点添加到数组中 ------ 数组存与这个点连接的结点
                    graph[child -> val].push_back(node -> val);
                    dfs(child);
                }
            }
        };
        // 相当于二维矩阵 来将一个树转化为图
        dfs(root);
        // 队列存拓扑排序的顺序  但还存遍历的次数
        queue<vector<int>> Q;
        Q.push({start,0});
        //相当于在有图的情况下 进行BFS
        // 存储遍历过的点
        unordered_set<int> visited;
        visited.insert(start);
        int time = 0;
        while(!Q.empty()){
            auto temp =Q.front() ;
            Q.pop();
            int nodeVal = temp[0];
            time = temp[1];
            // 遍历点对应的相连的结点
            for(int Val : graph[nodeVal]){
                if(!visited.count(Val)){
                    Q.push({Val,time+1});
                    visited.insert(Val);
                }
            }


        }
        return time;
    }
};

结算页面

相关推荐
YuCaiH7 分钟前
网络编程的基础知识
linux·笔记·嵌入式·网络通信
m0_6896182818 分钟前
突破亚微米光电子器件制造瓶颈!配体交换辅助打印技术实现全打印红外探测器
笔记·制造
代码不停25 分钟前
Java前缀和算法题目练习
java·开发语言·算法
courniche29 分钟前
分组密码常见结构简介
算法·密码学
涤生z33 分钟前
list.
开发语言·数据结构·c++·学习·算法·list
茜茜西西CeCe1 小时前
数字图像处理-图像增强(2)
人工智能·算法·计算机视觉·matlab·数字图像处理·图像增强·陷波滤波器
薰衣草23331 小时前
hot100练习-11
算法·leetcode
地平线开发者2 小时前
征程 6 | 工具链如何支持 Matmul/Conv 双 int16 输入量化?
人工智能·算法·自动驾驶
甄心爱学习2 小时前
数值计算-线性方程组的迭代解法
算法
stolentime2 小时前
SCP2025T2:P14254 分割(divide) 题解
算法·图论·组合计数·洛谷scp2025