微服务集成测试 -华为OD机试真题(A卷、JavaScript)

题目描述

现在有n个容器服务,服务的启动可能有一定的依赖性(有些服务启动没有依赖),其次,服务自身启动加载会消耗一些时间。

给你一个n × n 的二维矩阵useTime,其中useTime[i][i]=10表示服务i自身启动加载需要消耗10s,useTime[i][j]=1表示服务i启动依赖服务j启动完成,useTime[i][k]=0表示服务i启动不依赖服务k。其中0 <= i, j, k < n。服务之间没有循环依赖(不会出现环),若想对任意一个服务i进行集成测试(服务i自身也需要加载),求最少需要等待多少时间。

输入描述

第一行输入服务总量n,之后的n行表示服务启动的依赖关系以及自身启动加载耗时,最后输入k表示计算需要等待多少时间后,可以对服务k进行集成测试,其中1 <= k <= n, 1 <= n <= 100

输出描述

最少需要等待多少时间(单位:秒)后,可以对服务k进行集成测试。

示例1

复制代码
输入:
3
5 0 0
1 5 0
0 1 5
3


输出:
15

说明:
服务3启动依赖服务2,服务2启动依赖服务1,由于服务1、2、3自身加载都需要消耗5s,所以5+5+5=15s,需要等待15s后可以对服务3进行集成测试。

示例2

复制代码
输入:
3
5 0 0
1 10 1
1 0 11
2

输出:
26

说明:
服务2启动依赖服务1和服务3,服务3启动需要依赖服务1,服务1、2、3自身加载需要消耗5s、10s、11s,所以5+10+11=26s,需要等待26s后可以对服务2进行集成测试。

📌 题目分析

这道题涉及 有向无环图(DAG)上的最长路径问题 ,可以用 深度优先搜索(DFS)+ 记忆化搜索 来解决。

在这道题中:

  • 节点 代表 容器服务
  • 代表 服务之间的依赖关系
  • 节点的值 代表 服务自身启动的耗时
  • 目标 是计算对某个服务 k 进行集成测试的最少等待时间。

转换思维

题目等价于计算从所有依赖的服务出发,沿依赖路径到 k最长路径和


🧠 解题思路

  1. 建模为有向无环图(DAG)

    • n × n邻接矩阵 useTime 表示 依赖关系自身耗时
    • useTime[i][j] = 1 表示 i 依赖 j
    • useTime[i][i] 代表 服务 i 自身的加载时间
  2. 深度优先搜索(DFS)+ 记忆化搜索

    • 递归求解每个服务的最长路径 (即启动 k 之前所需的时间)。
    • 递归时:
      • 如果 i 依赖 j,则先计算 j 的时间。
      • maxTime = max(所有依赖的时间) + 自身启动时间
    • 使用 memo 数组存储计算过的值,避免重复计算。
  3. 最终答案

    • 计算从 所有依赖的服务出发到 k最长路径时间

💻 代码实现

✅ 代码优化 + 详细注释

javascript 复制代码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

// 记忆化数组,避免重复计算
let memo = {};

// 计算启动服务 `i` 需要的最小等待时间(DFS + 记忆化)
function dfs(useTime, i) {
    // 如果已经计算过,直接返回
    if (memo[i] !== undefined) return memo[i];

    let maxTime = 0;
    for (let k = 0; k < useTime.length; k++) {
        // `useTime[i][k] == 1` 表示 `i` 依赖 `k`,递归计算 `k`
        if (useTime[i][k] === 1 && i !== k) {
            maxTime = Math.max(maxTime, dfs(useTime, k));
        }
    }

    // 计算当前服务 `i` 需要的时间 = 最大依赖时间 + 自身启动时间
    memo[i] = maxTime + useTime[i][i];
    return memo[i];
}

void async function () {
    // 读取服务总数 `n`
    const n = parseInt(await readline());
    const useTime = [];

    // 读取 `n × n` 的矩阵
    for (let i = 0; i < n; i++) {
        let row = (await readline()).split(' ').map(Number);
        useTime.push(row);
    }

    // 读取 `k`,并转换为 0-based 索引
    let k = parseInt(await readline()) - 1;

    // 计算最少需要等待的时间
    console.log(dfs(useTime, k));

    rl.close();
}();

🚀 代码解析

  1. 数据读取

    • 先读取 n(服务数量)。
    • 读取 n × nuseTime 矩阵,表示服务依赖关系和自身启动时间。
    • 读取 k(需要计算的目标服务),并 转换为 0-based 索引
  2. 深度优先搜索(DFS)+ 记忆化

    • 维护 memo 数组 ,存储已经计算过的时间,避免重复计算(动态规划思想)。
    • 遍历 useTime[i][k] == 1 的依赖项,递归计算其 最长路径和
    • maxTime = max(所有依赖的时间) + 自身启动时间
  3. 最终输出

    • console.log(dfs(useTime, k)); 计算 k 需要的最少等待时间。

📊 复杂度分析

复杂度 说明
时间复杂度:O(n²) 由于是 DAG(无环图),每个服务最多遍历 n 次,每个 dfs() 调用最多递归 n 层,因此最坏情况是 O(n²)
空间复杂度:O(n) 主要存储 memo 数组 和递归栈,最坏情况下 O(n)

✅ 测试 & 运行示例

📌 示例 1

🔹 输入

复制代码
3
5 0 0
1 5 0
0 1 5
3

🔹 计算过程

复制代码
服务 3 依赖 服务 2
服务 2 依赖 服务 1
服务 1 自身耗时 5s
服务 2 自身耗时 5s
服务 3 自身耗时 5s
总时间 = 5 + 5 + 5 = 15s

🔹 输出

复制代码
15

📌 示例 2

🔹 输入

复制代码
3
5 0 0
1 10 1
1 0 11
2

🔹 计算过程

复制代码
服务 2 依赖 服务 1、服务 3
服务 3 依赖 服务 1
服务 1 自身耗时 5s
服务 3 自身耗时 11s(依赖 服务 1)
服务 2 自身耗时 10s(依赖 服务 1、服务 3)

最长路径 = 5 + 11 + 10 = 26s

🔹 输出

复制代码
26

🔎 总结

方法 特点 适用场景
DFS + 记忆化 递归遍历 DAG,存储计算结果,避免重复计算 适用于 有向无环图(DAG)上的最长路径
拓扑排序 + 动态规划(DP) 依赖 入度计算 ,从 无依赖的节点 逐步计算 适用于 大规模 DAG 依赖关系

✅ 方案优势

  • 使用 DFS + 记忆化,避免重复计算,优化 O(n²)
  • 代码简洁,符合递归求最长路径的思路
  • 无环保证,直接计算最长路径,无需拓扑排序

🔚 结论

这道题本质上是 有向无环图(DAG)上的最长路径问题 ,可以用 DFS + 记忆化 优化。通过递归计算 最长依赖链的时间 ,最终求出 启动服务 k 需要的最少时间

如果数据规模更大(如 n > 10^5),可以考虑拓扑排序+DP 解法! 🚀

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

相关推荐
KangkangLoveNLP6 分钟前
手动实现一个迷你Llama:使用SentencePiece实现自己的tokenizer
人工智能·深度学习·学习·算法·transformer·llama
独好紫罗兰10 分钟前
洛谷题单3-P1420 最长连号-python-流程图重构
开发语言·python·算法
美食制作家11 分钟前
【无标题】Threejs第一个3D场景
javascript·three
柯ran35 分钟前
数据结构|排序算法(一)快速排序
数据结构·算法·排序算法
pipip.39 分钟前
搜索二维矩阵
数据结构·算法·矩阵
uhakadotcom1 小时前
图像识别中的三大神经网络:Inception、ResNet和VGG
算法·面试·github
努力学计算机的小白一枚1 小时前
146. LRU 缓存 && 带TTL的LRU缓存实现(拓展)
算法·缓存
uhakadotcom1 小时前
DeepFM算法:提升CTR预估和推荐系统的强大工具
算法·面试·github
HelloRevit1 小时前
React DndKit 实现类似slack 类别、频道拖动调整位置功能
前端·javascript·react.js
evolution_language1 小时前
LintCode第974题-求矩阵各节点的最短路径(以0为标准)
算法·最短路径·广度优先搜索