华为OD笔试机试 - 悄悄话 (c++ 2024年C卷D卷)

华为OD机试(C卷+D卷)2024真题目录(Java & c++ & python)

题目描述

给定一个二叉树,每个节点上站一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。

初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二叉树所有节点上的人都接收到悄悄话花费的时间。

输入描述

给定二叉树

0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2

注:-1表示空节点
在这里插入图片描述

输出描述

返回所有节点都接收到悄悄话花费的时间

38

示例1

输入

0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2

输出

38

解题思路

层序遍历序列中,父子节点存在如下关系:

如果父节点在序列中的索引是k,则其两个子节点在序列中的索引分别为 2k+1, 2k+2

而悄悄话的传递,其实父节点将自身得到消息的时延累加到其各个子节点上,最终叶子节点中最大的时延值就是:二叉树所有节点上的人都接收到悄悄话花费的时间

在这里插入图片描述

参考代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> delays;
    int delay;
    while (cin >> delay) {
        delays.emplace_back(delay);
    }

    // 记录题解
    int max_delay = 0;

    // 根节点的索引是0
    deque<int> node_queue;
    node_queue.emplace_back(0);

    while (!node_queue.empty()) {
        int parent_index = node_queue.front(); // 父节点索引
        node_queue.pop_front();

        int left_child_index = 2 * parent_index + 1; // 左子节点索引
        int right_child_index = 2 * parent_index + 2; // 右子节点索引

        // 父节点是否存在左子节点
        bool left_child_exists = left_child_index < delays.size() && delays[left_child_index] != -1;
        // 父节点是否存在右子节点
        bool right_child_exists = right_child_index < delays.size() && delays[right_child_index] != -1;

        // 如果存在左子节点
        if (left_child_exists) {
            delays[left_child_index] += delays[parent_index];
            node_queue.push_back(left_child_index);
        }

        // 如果存在右子节点
        if (right_child_exists) {
            delays[right_child_index] += delays[parent_index];
            node_queue.push_back(right_child_index);
        }

        // 如果是叶子节点
        if (!left_child_exists && !right_child_exists) {
            // 保留叶子节点中最大时延
            max_delay = max(max_delay, delays[parent_index]);
        }
    }

    cout << max_delay << endl;

    return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值