【Leetcode】636. Exclusive Time of Functions
阿新 • • 發佈:2021-02-09
技術標籤:LC 棧、佇列、串及其他資料結構leetcodejava演算法
題目地址:
https://leetcode.com/problems/exclusive-time-of-functions/
對於一個單執行緒,它總共呼叫過
n
n
n個不同的函式,給定其函式呼叫的log,這個log是個字串陣列,每個陣列的格式形如"id:start:x"
或者"id:end:x"
,表示編號為id的函式在
x
x
x這個時間戳開始(或結束)了。要求返回每個函式的獨佔的呼叫時間(也就是它們位於執行緒棧頂的時間。注意,開始和結束兩個時刻都是屬於呼叫函式獨佔時間的,這兩個時刻所代表的時間,比如花了一秒,都要計入)。
思路是用棧,直接模擬函式呼叫過程,然後累加每個函式的獨佔時間。即,遇到函式開始,就把呼叫它的函式的獨佔時間累加一下,並把當前函式id入棧;遇到函式結束,則把它自己的獨佔時間累加一下,並且棧頂出棧(由計算機函式呼叫的設計,此時棧頂的id一定就是當前函式的id)。由於累加的時候,要知道棧頂函式的一段連續獨佔時間片段是啥時候開始的,這可以用一個變數記錄一下。程式碼如下:
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
public class Solution {
public int [] exclusiveTime(int n, List<String> logs) {
int[] res = new int[n];
// 存正在呼叫的函式的id
Deque<Integer> stack = new ArrayDeque<>();
// last存的是棧頂函式的連續獨佔時間片段的開始時間
int last = 0;
for (String log : logs) {
String[] split = log.split(":" );
// 解析出函式id,是開始還是結束,以及時間戳
int id = Integer.parseInt(split[0]), time = Integer.parseInt(split[2]);
String op = split[1];
if ("start".equals(op)) {
// 如果當前函式是開始,並且如果它是別的函式呼叫的,那麼呼叫它的函式的時間應該累加一下
if (!stack.isEmpty()) {
res[stack.peek()] += time - last;
}
stack.push(id);
last = time;
} else {
// 棧頂函式呼叫結束了,它的時間也要累加一下。注意這裡要把呼叫開始的那一刻也要算進去
res[stack.pop()] += time - last + 1;
// 此時棧頂變成了呼叫當前函式的那個函式,
// 它的又一獨佔時間片段開始了,開始時間是當前函式結束的時間 + 1
last = time + 1;
}
}
return res;
}
}
時空複雜度 O ( N ) O(N) O(N), N N N是log的長度,空間 O ( n ) O(n) O(n)。