稀碎从零算法笔记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;
    }
};

结算页面

相关推荐
IT猿手2 小时前
2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB
人工智能·python·算法·数学建模·matlab·智能优化算法
Dream it possible!5 小时前
LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)
c++·算法·leetcode
修己xj6 小时前
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
算法
开心比对错重要7 小时前
leetcode69.x 的平方根
数据结构·算法·leetcode
美狐美颜sdk7 小时前
什么是美颜SDK?从几何变换到深度学习驱动的美颜算法详解
人工智能·深度学习·算法·美颜sdk·第三方美颜sdk·视频美颜sdk·美颜api
m0_461502697 小时前
【贪心算法1】
算法·贪心算法
Doopny@7 小时前
数字组合(信息学奥赛一本通-1291)
数据结构·算法·动态规划
原来是猿8 小时前
蓝桥备赛(13)- 链表和 list(上)
开发语言·数据结构·c++·算法·链表·list
项目申报小狂人8 小时前
高性能算法NGO!北方苍鹰优化算法(Northern Goshawk Optimization,NGO)
算法·数学建模
且听风吟ayan8 小时前
leetcode day26 重复的子字符串
算法·leetcode·c#