leetcode2389--感染二叉树需要的总时间

文章介绍了如何使用深度优先搜索(DFS)和广度优先搜索(BFS)的方法解决二叉树中节点感染问题,目标是找到所有节点被感染所需的时间。给出了三种不同的实现策略,包括基于图的构建、利用哈希表跟踪父节点以及一次遍历计算最大深度。
摘要由CSDN通过智能技术生成

1. 题意

给定一个节点,每秒该节点会感染相邻的节点,受感染的节点下一秒也会感染周围节点;

求使得所有节点感染的时间

2. 题解

2.1 dfs建图+bfs搜索层次

我们将目标节点找到,并从该节点出发找到以该节点形成的树的深度即可。

  • 我的代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {


public:


    // * transform tree to graph

    // * sparse graph

    void build_graph(TreeNode * root, vector<vector<int>> &g) {
        if (nullptr == root)
            return;
        if ( root->left) {
            g[root->val].push_back( root->left->val);
            g[root->left->val].push_back(root->val);
            build_graph(root->left, g);
        }
        if ( root->right ) {
            g[root->val].push_back(root->right->val);
            g[root->right->val].push_back(root->val);
            build_graph(root->right, g);
        }
    }


    int amountOfTime(TreeNode* root, int start) {
        
        const int MAXN = 1e5 + 1;
        vector<vector<int>> g(MAXN, vector<int>());

        build_graph(root, g);

        int ans = 0;
        int last = start;
        queue<int> q;
        q.push(start);
        vector<int> vis(MAXN, 0);


        while (!q.empty()) {
            int cur = q.front();
            q.pop();vis[cur] = 1;

            for (int v:g[cur])
                if (!vis[v])
                    q.push(v);
            if (cur == last) {
                ans++;
                last = q.back();
            }

        }

        return ans - 1;
    }
};

2.2 dfs建图+dfs求深度

我们需要找到每个节点的父节点,并且用一个from来表示当前节点是从哪来的以避免重复遍历。

  • 我的代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {

public:


    // * transform tree to graph

    // * sparse graph

    void get_fa(unordered_map<int,TreeNode *> &fa, TreeNode *root, 
        int start, TreeNode *&start_node) {
        if (root == nullptr)
            return;
        if ( root->left)
            fa[root->left->val] = root;
        if ( root->right)
            fa[root->right->val] = root;
        if ( root->val == start)
            start_node = root;


        get_fa(fa, root->left, start, start_node );
        get_fa(fa, root->right, start, start_node );
    }

    int getDepth(TreeNode *root, int from,const unordered_map<int,TreeNode*> &fa) {
        
        if ( nullptr == root)
            return -1;

        int llen = -1;
        int rlen = -1;
        int flen = -1;

        if ( root->left && root->left->val != from)
            llen = getDepth(root->left, root->val, fa);
        if ( root->right && root->right->val != from )
            rlen = getDepth( root->right, root->val, fa);
        
        
        if (fa.find(root->val) != fa.end() &&
            fa.at(root->val)->val != from) {
           // cout << "fa-" << fa.at(root->val)->val << endl;
            flen = getDepth( fa.at(root->val), root->val, fa);
        }
        

        int ans = max(llen, rlen);
        ans = max(flen, ans);

        return ans + 1;
    }

    int amountOfTime(TreeNode* root, int start) {
        
        unordered_map<int,TreeNode *> fa;
        

        TreeNode *start_node;
        get_fa( fa, root, start, start_node);
     


        return  getDepth(start_node, -1, fa);
    }
};
  • 03xf题解

TreeNode* fa[100001]; // 哈希表会超时,改用数组

class Solution {
    int start;
    TreeNode* start_node;

    void dfs(TreeNode* node, TreeNode* from) {
        if (node == nullptr) {
            return;
        }
        fa[node->val] = from; // 记录每个节点的父节点
        if (node->val == start) {
            start_node = node; // 找到 start
        }
        dfs(node->left, node);
        dfs(node->right, node);
    }

    int maxDepth(TreeNode* node, TreeNode* from) {
        if (node == nullptr) {
            return -1; // 注意这里是 -1,因为 start 的深度为 0
        }
        int res = -1;
        if (node->left != from) {
            res = max(res, maxDepth(node->left, node));
        }
        if (node->right != from) {
            res = max(res, maxDepth(node->right, node));
        }
        if (fa[node->val] != from) {
            res = max(res, maxDepth(fa[node->val], node));
        }
        return res + 1;
    }

public:
    int amountOfTime(TreeNode* root, int start) {
        this->start = start;
        dfs(root, nullptr);
        return maxDepth(start_node, start_node);
    }
};

作者:灵茶山艾府
链接:https://leetcode.cn/problems/amount-of-time-for-binary-tree-to-be-infected/solutions/2753470/cong-liang-ci-bian-li-dao-yi-ci-bian-li-tmt0x/comments/2287846/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2.3 一次遍历
  • 03xf
class Solution {
    int ans = 0, start;

    pair<int, bool> dfs(TreeNode* node) {
        if (node == nullptr) {
            return {0, false};
        }
        auto [l_len, l_found] = dfs(node->left);
        auto [r_len, r_found] = dfs(node->right);
        if (node->val == start) {
            // 计算子树 start 的最大深度
            // 注意这里和方法一的区别,max 后面没有 +1,所以算出的也是最大深度
            ans = max(l_len, r_len);
            return {1, true}; // 找到了 start
        }
        if (l_found || r_found) {
            // 只有在左子树或右子树包含 start 时,才能更新答案
            ans = max(ans, l_len + r_len); // 两条链拼成直径
            // 保证 start 是直径端点
            return {(l_found ? l_len : r_len) + 1, true};
        }
        return {max(l_len, r_len) + 1, false};
    }

public:
    int amountOfTime(TreeNode* root, int start) {
        this->start = start;
        dfs(root);
        return ans;
    }
};

作者:灵茶山艾府
链接:https://leetcode.cn/problems/amount-of-time-for-binary-tree-to-be-infected/solutions/2753470/cong-liang-ci-bian-li-dao-yi-ci-bian-li-tmt0x/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值