636. 函数的独占时间

66 阅读2分钟

有一个 单线程 CPU 正在运行一个含有 n 道函数的程序。每道函数都有一个位于  0 和 n-1 之间的唯一标识符。

函数调用 存储在一个 调用栈 上 :当一个函数调用开始时,它的标识符将会推入栈中。而当一个函数调用结束时,它的标识符将会从栈中弹出。标识符位于栈顶的函数是 当前正在执行的函数 。每当一个函数开始或者结束时,将会记录一条日志,包括函数标识符、是开始还是结束、以及相应的时间戳。

给你一个由日志组成的列表 logs ,其中 logs[i] 表示第 i 条日志消息,该消息是一个按 "{function_id}:{"start" | "end"}:{timestamp}" 进行格式化的字符串。例如,"0:start:3" 意味着标识符为 0 的函数调用在时间戳 3 的 起始开始执行 ;而 "1:end:2" 意味着标识符为 1 的函数调用在时间戳 2 的 末尾结束执行。注意,函数可以 调用多次,可能存在递归调用 。

函数的 独占时间 定义是在这个函数在程序所有函数调用中执行时间的总和,调用其他函数花费的时间不算该函数的独占时间。例如,如果一个函数被调用两次,一次调用执行 2 单位时间,另一次调用执行 1 单位时间,那么该函数的 独占时间 为 2 + 1 = 3 。

以数组形式返回每个函数的 独占时间 ,其中第 i 个下标对应的值表示标识符 i 的函数的独占时间。

var exclusiveTime = function(n, logs) {
    // let matrix = logs.map((item)=> item.split(':'))
    // console.log(matrix)
    let ans = new Array(n).fill(0), stack = [];
    for(let i =0,pre =0; i< logs.length;i++){
        let [fn, status, time] = logs[i].split(':');
        fn = Number(fn);
        time = Number(time)
        /* 入栈的情况下时间间隔属于上一个任务 也就是栈顶元素 */
        if(status === 'start'){
            let id = stack[stack.length -1]
           if(stack.length){
            ans[id]+=time - pre ;
            }
            pre = time;
            stack.push(fn);
        }else {
            /* 出栈时 时间间隔还是上一个任务也是当前任务  不过这里需要+1 对应的pre也要+1 */
         if(stack.length){
            ans[fn]+=time - pre +1 ;
            }   
        pre = time +1
            stack.pop()
        }
    }
    return ans

};