636 Exclusive Time of Functions

# 1. Question

Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find the exclusive time of these functions.
Each function has a unique id, start from0ton-1. A function may be called recursively or by another function.
A log is a string has this format :`function_id:start_or_end:timestamp`. For example,`"0:start:0"`means function 0 starts from the very beginning of time 0.`"0:end:0"`means function 0 ends to the very end of time 0.
Exclusive time of a function is defined as the time spent within this function, the time spent by calling other functions should not be considered as this function's exclusive time. You should return the exclusive time of each function sorted by their function id.
Example 1:
1
Input:
2
n = 2
3
logs =
4
["0:start:0",
5
"1:start:2",
6
"1:end:5",
7
"0:end:6"]
8
9
Output: [3, 4]
10
11
Explanation:
12
Function 0 starts at time 0, then it executes 2 units of time and reaches the end of time 1.
13
Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5.
14
Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time.
15
So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time.
Copied!
Note:
1. 1.
Input logs will be sorted by timestamp, NOT log id.
2. 2.
Your output should be sorted by function id, which means the 0th element of your output corresponds to the exclusive time of function 0.
3. 3.
Two functions won't start or end at the same time.
4. 4.
Functions could be called recursively, and will always end.
5. 5.
1 <= n <= 100

# 2. Implementation

(1) Stack

• 我们应该将每个时间作为一个单位判断, 即把每个时间想象成一个bucket
• 当log中的function是start时，表示log的时间点是下一个区间的起点，那么对于当前正在运行的function(stack顶存的function id)，其运行时间应该是当前log的时间curTime减去上次记录的时间preTime。因为curTime是下一个区间的起点，所以不应该加入当前的计算
• 当log中的function是end时，表示log的时间点是当前区间的终点，所以当前运行的function的所花的时间应该是curTime - preTime + 1，因为curTime此时被算作当前的区间，应该加入当期的计算，同时preTime更新为curTime + 1，表示下一个区间的起点
1
class Solution {
2
public int[] exclusiveTime(int n, List<String> logs) {
3
if (n <= 0 || logs == null || logs.size() == 0) {
4
return new int;
5
}
6
7
Stack<Integer> stack = new Stack();
8
// preTime is the start of interval
9
int preTime = 0;
10
int curTime = 0;
11
12
int[] res = new int[n];
13
14
for (String log : logs) {
15
String[] parts = log.split(":");
16
int id = Integer.parseInt(parts);
17
curTime = Integer.parseInt(parts);
18
19
if (parts.equals("start")) {
20
if (!stack.isEmpty()) {
21
// curTime is the start of next interval, it doesn't belong to
22
// current interval, should not count it here
23
res[stack.peek()] += curTime - preTime;
24
}
25
stack.push(id);
26
preTime = curTime;
27
}
28
else {
29
// curTime is the end of current interval, we should count it
30
// by plus 1 here
31
res[stack.pop()] += curTime - preTime + 1;
32
// Update preTime to start of next interval by plus 1
33
preTime = curTime + 1;
34
}
35
}
36
return res;
37
}
38
}
Copied!

# 3. Time & Space Complexity

Stack: 时间复杂度O(n), 空间复杂度O(n)