636. Exclusive Time of Functions

On a single-threaded CPU, we execute a program containing n functions. Each function has a unique ID between 0 and n-1.

Function calls are stored in a call stack: when a function call starts, its ID is pushed onto the stack, and when a function call ends, its ID is popped off the stack. The function whose ID is at the top of the stack is the current function being executed. Each time a function starts or ends, we write a log with the ID, whether it started or ended, and the timestamp.

You are given a list logs, where logs[i] represents the ith log message formatted as a string "{function_id}:{"start" | "end"}:{timestamp}". For example, "0:start:3" means a function call with function ID 0 started at the beginning of timestamp 3, and "1:end:2" means a function call with function ID 1 ended at the end of timestamp 2. Note that a function can be called multiple times, possibly recursively.

A function's exclusive time is the sum of execution times for all function calls in the program. For example, if a function is called twice, one call executing for 2 time units and another call executing for 1 time unit, the exclusive time is 2 + 1 = 3.

Return the exclusive time of each function in an array, where the value at the ith index represents the exclusive time for the function with ID i.

 

Example 1:


Input: n = 2, logs = ["0:start:0","1:start:2","1:end:5","0:end:6"]
Output: [3,4]
Explanation:
Function 0 starts at the beginning of time 0, then it executes 2 for units of time and reaches the end of time 1.
Function 1 starts at the beginning of time 2, executes for 4 units of time, and ends at the end of time 5.
Function 0 resumes execution at the beginning of time 6 and executes for 1 unit of time.
So function 0 spends 2 + 1 = 3 units of total time executing, and function 1 spends 4 units of total time executing.
Example 2:

Input: n = 1, logs = ["0:start:0","0:start:2","0:end:5","0:start:6","0:end:6","0:end:7"]
Output: [8]
Explanation:
Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
Function 0 (initial call) resumes execution then immediately calls itself again.
Function 0 (2nd recursive call) starts at the beginning of time 6 and executes for 1 unit of time.
Function 0 (initial call) resumes execution at the beginning of time 7 and executes for 1 unit of time.
So function 0 spends 2 + 4 + 1 + 1 = 8 units of total time executing.
Example 3:

Input: n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:6","1:end:6","0:end:7"]
Output: [7,1]
Explanation:
Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
Function 0 (initial call) resumes execution then immediately calls function 1.
Function 1 starts at the beginning of time 6, executes 1 units of time, and ends at the end of time 6.
Function 0 resumes execution at the beginning of time 6 and executes for 2 units of time.
So function 0 spends 2 + 4 + 1 = 7 units of total time executing, and function 1 spends 1 unit of total time executing.
Example 4:

Input: n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:7","1:end:7","0:end:8"]
Output: [8,1]
Example 5:

Input: n = 1, logs = ["0:start:0","0:end:0"]
Output: [1]
 

Constraints:

1 <= n <= 100
1 <= logs.length <= 500
0 <= function_id < n
0 <= timestamp <= 109
No two start events will happen at the same timestamp.
No two end events will happen at the same timestamp.
Each function has an "end" log for each "start" log.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/exclusive-time-of-functions
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

需要注意的是,在start项里面,时间点是开始的时刻,即"1:start:2","1:end:5"这两个点,就要从2-3-4-5计算,就是四个时间间隔。

次题目用stack解,因为最后一个开始的一定最先结束,统计出来。stack存放着,遍历到的任务的id,用一个lastime标记现在遍历到的时间终点。

 

class Solution {
    public int[] exclusiveTime(int n, List<String> logs) {
        Stack<Integer>stack = new Stack<>();
        int []ans = new int[n];
        int lastTime = 0;
        for (String log : logs) {
            String[]strings = log.split(":");
            int id = Integer.parseInt(strings[0]);
            int time = Integer.parseInt(strings[2]);
            // 如果stack为空,直接把id放入stack,同时更新lastime时间
            if (stack.empty()) {
                stack.push(id);
                lastTime = time;
                continue;
            }
            // 走到这里,说明stack里面肯定有未完成的任务。
            // 不管这次遍历到的是start还是end,都需要把stack中最上面的任务的时间算上。因为:
            // 如果是start,那么stack上top的任务,就会被中断(也或者不会,可能这次的start的任务和stack上top任务编号一样,但是这种情况也可以这样计算)
            // 那么,说明,在本次遍历到的任务之前,CPU都在执行stcak中的top任务,那么就需要把top上的这个任务的时间加到最终结果中。
            // 如果是end,那说明此任务结束了,那么也是一样要把之间的执行时间加上。
            ans[stack.peek()] += time - lastTime;
            // 更新当前走到的时间点为遍历到的time值。
            lastTime = time;
            if (strings[1].compareTo("start") == 0) {
                // 如果这次是start任务,那么把任务id进栈
                stack.push(id);
            } else {
                // 如果是end任务,那么还要做多一个处理,就是把这一个时刻的时间算上。
                // 正如上面例子,"1:start:2","1:end:5",那么就要把签名少算的时刻5给算上。
                // 同时lastTime也要加一,因为这个时刻的时间,是已经被算了的。
                int top = stack.pop();
                ans[top]++;
                lastTime++;
            }
        }
        return ans;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值