• 稀碎从零算法笔记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 来存相连的点的val 
    转化为图后可以进行从 start 开始的 BFS —- 用queue来存拓扑排序的点的 【相连的点】 。遍历完一次后就可以将【相连的点】添加到 queue 中。 
    考虑到一个点可能被多个点相连 进而可能被访问多次,可以用 visit 数组来存一下是否被访问过

    C++代码

    1. class Solution {
    2. public:
    3. int amountOfTime(TreeNode* root, int start) {
    4. // int存time vector 存孩子/父节点
    5. unordered_map<int,vector<int>>graph;
    6. // lambda定义dfs
    7. function<void(TreeNode *)>dfs = [&](TreeNode * node){
    8. //将左右孩子整合为child
    9. for(TreeNode *child : vector {node ->left,node -> right}){
    10. if(child != nullptr){
    11. // 将孩子结点添加到数组中 —— 数组存相连的点
    12. graph[node -> val].push_back(child -> val);
    13. // 将父亲结点添加到数组中 —— 数组存与这个点连接的结点
    14. graph[child -> val].push_back(node -> val);
    15. dfs(child);
    16. }
    17. }
    18. };
    19. // 相当于二维矩阵 来将一个树转化为图
    20. dfs(root);
    21. // 队列存拓扑排序的顺序 但还存遍历的次数
    22. queueint>> Q;
    23. Q.push({start,0});
    24. //相当于在有图的情况下 进行BFS
    25. // 存储遍历过的点
    26. unordered_set<int> visited;
    27. visited.insert(start);
    28. int time = 0;
    29. while(!Q.empty()){
    30. auto temp =Q.front() ;
    31. Q.pop();
    32. int nodeVal = temp[0];
    33. time = temp[1];
    34. // 遍历点对应的相连的结点
    35. for(int Val : graph[nodeVal]){
    36. if(!visited.count(Val)){
    37. Q.push({Val,time+1});
    38. visited.insert(Val);
    39. }
    40. }
    41. }
    42. return time;
    43. }
    44. };

    结算页面

  • 相关阅读:
    众佰诚:抖音开通橱窗的要求和流程有什么
    【Java复习】线程安全的 HashMap --- ConcurrentHashMap
    scau CSAPP 第二章家庭作业
    Java中泛型
    (附源码)ssm人力资源管理系统 毕业设计 271621
    阿里云服务器系统怎么选?Alibaba Cloud Linux操作系统介绍
    Codeforces Round #474 (Div. 1 + Div. 2) - C, F
    FPGA project : usrt_rs232
    JavaScript代码执行
    前端 js 之 promise( 第一版 23.11.18) 09
  • 原文地址:https://blog.csdn.net/m0_63356844/article/details/138172296