Skip to content

Commit c4aaf91

Browse files
Merge pull request SharingSource#621 from SharingSource/ac_oier
✨feat: add 636
2 parents 8dbed62 + d8c6143 commit c4aaf91

File tree

4 files changed

+160
-4
lines changed

4 files changed

+160
-4
lines changed

Index/栈.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
| [341. 扁平化嵌套列表迭代器](https://leetcode-cn.com/problems/flatten-nested-list-iterator/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/flatten-nested-list-iterator/solution/yi-ti-shuang-jie-dfsdui-lie-di-gui-zhan-kvwhy/) | 中等 | 🤩🤩🤩 |
99
| [385. 迷你语法分析器](https://leetcode-cn.com/problems/mini-parser/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/mini-parser/solution/by-ac_oier-zuy6/) | 中等 | 🤩🤩🤩🤩🤩 |
1010
| [591. 标签验证器](https://leetcode-cn.com/problems/tag-validator/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/tag-validator/solution/by-ac_oier-9l8z/) | 困难 | 🤩🤩🤩🤩 |
11+
| [636. 函数的独占时间](https://leetcode.cn/problems/exclusive-time-of-functions/) | [LeetCode 题解链接](https://leetcode.cn/problems/exclusive-time-of-functions/solution/by-ac_oier-z3ed/) | 中等 | 🤩🤩🤩🤩🤩 |
1112
| [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 |
1213
| [735. 行星碰撞](https://leetcode.cn/problems/asteroid-collision/) | [LeetCode 题解链接](https://leetcode.cn/problems/asteroid-collision/solution/by-ac_oier-p4qh/) | 中等 | 🤩🤩🤩🤩🤩 |
1314
| [1190. 反转每对括号间的子串](https://leetcode-cn.com/problems/reverse-substrings-between-each-pair-of-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reverse-substrings-between-each-pair-of-parentheses/solution/gong-shui-san-xie-shi-yong-shuang-duan-d-r35q/) | 中等 | 🤩🤩🤩🤩🤩 |

Index/模拟.md

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
| [594. 最长和谐子序列](https://leetcode-cn.com/problems/longest-harmonious-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-harmonious-subsequence/solution/gong-shui-san-xie-yi-ti-shuang-jie-hua-d-quuh/) | 简单 | 🤩🤩🤩🤩 |
8484
| [598. 范围求和 II](https://leetcode-cn.com/problems/range-addition-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/range-addition-ii/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-006h/) | 简单 | 🤩🤩🤩 |
8585
| [599. 两个列表的最小索引总和](https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/solution/by-ac_oier-oh5b/) | 简单 | 🤩🤩🤩🤩 |
86+
| [636. 函数的独占时间](https://leetcode.cn/problems/exclusive-time-of-functions/) | [LeetCode 题解链接](https://leetcode.cn/problems/exclusive-time-of-functions/solution/by-ac_oier-z3ed/) | 中等 | 🤩🤩🤩🤩🤩 |
8687
| [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/set-mismatch/solution/gong-shui-san-xie-yi-ti-san-jie-ji-shu-s-vnr9/) | 简单 | 🤩🤩🤩 |
8788
| [661. 图片平滑器](https://leetcode-cn.com/problems/image-smoother/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/image-smoother/solution/by-ac_oier-nn3v/) | 简单 | 🤩🤩🤩🤩 |
8889
| [682. 棒球比赛](https://leetcode-cn.com/problems/baseball-game/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/baseball-game/solution/by-ac_oier-4mhz/) | 简单 | 🤩🤩🤩🤩 |

LeetCode/1401-1410/1408. 数组中的字符串匹配(简单).md

+5-4
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ Tag : 「模拟」
4242

4343
---
4444

45-
## 模拟
45+
### 模拟
4646

4747
根据题意进行模拟即可。
4848

49-
代码:
50-
```Java []
49+
Java 代码:
50+
```Java
5151
class Solution {
5252
public List<String> stringMatching(String[] ss) {
5353
List<String> ans = new ArrayList<>();
@@ -65,7 +65,8 @@ class Solution {
6565
}
6666
}
6767
```
68-
```TypeScript []
68+
TypeScript 代码:
69+
```TypeScript
6970
function stringMatching(ss: string[]): string[] {
7071
const ans = new Array<string>()
7172
const n = ss.length
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[636. 函数的独占时间](https://leetcode.cn/problems/exclusive-time-of-functions/solution/by-ac_oier-z3ed/)** ,难度为 **中等**
4+
5+
Tag : 「模拟」、「栈」
6+
7+
8+
9+
有一个单线程 `CPU` 正在运行一个含有 `n` 道函数的程序。每道函数都有一个位于  `0``n-1` 之间的唯一标识符。
10+
11+
函数调用 存储在一个调用栈上 :当一个函数调用开始时,它的标识符将会推入栈中。而当一个函数调用结束时,它的标识符将会从栈中弹出。标识符位于栈顶的函数是当前正在执行的函数。每当一个函数开始或者结束时,将会记录一条日志,包括函数标识符、是开始还是结束、以及相应的时间戳。
12+
13+
给你一个由日志组成的列表 `logs` ,其中 `logs[i]` 表示第 `i` 条日志消息,该消息是一个按 `"{function_id}:{"start" | "end"}:{timestamp}"` 进行格式化的字符串。例如,`"0:start:3"` 意味着标识符为 `0` 的函数调用在时间戳 `3` 的 起始开始执行 ;而 `"1:end:2"` 意味着标识符为 `1` 的函数调用在时间戳 `2` 的末尾结束执行。注意,函数可以调用多次,可能存在递归调用 。
14+
15+
函数的「独占时间」定义是在这个函数在程序所有函数调用中执行时间的总和,调用其他函数花费的时间不算该函数的独占时间。例如,如果一个函数被调用两次,一次调用执行 `2` 单位时间,另一次调用执行 `1` 单位时间,那么该函数的独占时间为 `2 + 1 = 3`
16+
17+
以数组形式返回每个函数的独占时间,其中第 `i` 个下标对应的值表示标识符 `i` 的函数的独占时间。
18+
19+
示例 1:
20+
![](https://assets.leetcode.com/uploads/2019/04/05/diag1b.png)
21+
```
22+
输入:n = 2, logs = ["0:start:0","1:start:2","1:end:5","0:end:6"]
23+
24+
输出:[3,4]
25+
26+
解释:
27+
函数 0 在时间戳 0 的起始开始执行,执行 2 个单位时间,于时间戳 1 的末尾结束执行。
28+
函数 1 在时间戳 2 的起始开始执行,执行 4 个单位时间,于时间戳 5 的末尾结束执行。
29+
函数 0 在时间戳 6 的开始恢复执行,执行 1 个单位时间。
30+
所以函数 0 总共执行 2 + 1 = 3 个单位时间,函数 1 总共执行 4 个单位时间。
31+
```
32+
示例 2:
33+
```
34+
输入:n = 1, logs = ["0:start:0","0:start:2","0:end:5","0:start:6","0:end:6","0:end:7"]
35+
36+
输出:[8]
37+
38+
解释:
39+
函数 0 在时间戳 0 的起始开始执行,执行 2 个单位时间,并递归调用它自身。
40+
函数 0(递归调用)在时间戳 2 的起始开始执行,执行 4 个单位时间。
41+
函数 0(初始调用)恢复执行,并立刻再次调用它自身。
42+
函数 0(第二次递归调用)在时间戳 6 的起始开始执行,执行 1 个单位时间。
43+
函数 0(初始调用)在时间戳 7 的起始恢复执行,执行 1 个单位时间。
44+
所以函数 0 总共执行 2 + 4 + 1 + 1 = 8 个单位时间。
45+
```
46+
示例 3:
47+
```
48+
输入:n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:6","1:end:6","0:end:7"]
49+
50+
输出:[7,1]
51+
52+
解释:
53+
函数 0 在时间戳 0 的起始开始执行,执行 2 个单位时间,并递归调用它自身。
54+
函数 0(递归调用)在时间戳 2 的起始开始执行,执行 4 个单位时间。
55+
函数 0(初始调用)恢复执行,并立刻调用函数 1 。
56+
函数 1在时间戳 6 的起始开始执行,执行 1 个单位时间,于时间戳 6 的末尾结束执行。
57+
函数 0(初始调用)在时间戳 7 的起始恢复执行,执行 1 个单位时间,于时间戳 7 的末尾结束执行。
58+
所以函数 0 总共执行 2 + 4 + 1 = 7 个单位时间,函数 1 总共执行 1 个单位时间。
59+
```
60+
示例 4:
61+
```
62+
输入:n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:7","1:end:7","0:end:8"]
63+
64+
输出:[8,1]
65+
```
66+
示例 5:
67+
```
68+
输入:n = 1, logs = ["0:start:0","0:end:0"]
69+
70+
输出:[1]
71+
```
72+
73+
提示:
74+
* $1 <= n <= 100$
75+
* $1 <= logs.length <= 500$
76+
* $0 <= function_id < n$
77+
* $0 <= timestamp <= 10^9$
78+
* 两个开始事件不会在同一时间戳发生
79+
* 两个结束事件不会在同一时间戳发生
80+
* 每道函数都有一个对应 `"start"` 日志的 `"end"` 日志
81+
82+
---
83+
84+
### 模拟
85+
86+
我们使用「栈」来模拟执行过程:当一个函数被调用(`op = start`)时,压入栈内,当函数调用完成(`op = end`)时,从栈顶弹出(此时栈顶元素必然是该结束函数的入栈记录),使用变量 `cur` 记录当前时间。
87+
88+
从前往后处理所有的 $log[i]$,根据 $log[i]$ 是属于函数调用还是函数结束进行分情况讨论:
89+
90+
* 当 $log[i]$ 为函数调用:此时从该函数的调用发起时间 `ts` 到上一次记录的当前时间,都是前一函数的执行时间,因此可以将 `ts - cur` 累加到栈帧中的前一函数。即若栈不为空,则将该时间累加到栈顶对应的函数上,然后将 $log[i]$ 入栈,同时更新当前时间;
91+
* 当 $log[i]$ 为函数结束:此时栈顶元素必然是该函数的调用记录,此时 $log[i]$ 的结束时间与上一次记录的当前时间的时长 `ts - cur + 1`,必然是该函数的执行时间,将其累加到当前函数中,并更新当前时间。
92+
93+
Java 代码:
94+
```Java
95+
class Solution {
96+
public int[] exclusiveTime(int n, List<String> logs) {
97+
int[] ans = new int[n];
98+
Deque<Integer> d = new ArrayDeque<>();
99+
int cur = -1;
100+
for (String log : logs) {
101+
String[] ss = log.split(":");
102+
int idx = Integer.parseInt(ss[0]), ts = Integer.parseInt(ss[2]);
103+
if (ss[1].equals("start")) {
104+
if (!d.isEmpty()) ans[d.peekLast()] += ts - cur;
105+
d.addLast(idx);
106+
cur = ts;
107+
} else {
108+
int func = d.pollLast();
109+
ans[func] += ts - cur + 1;
110+
cur = ts + 1;
111+
}
112+
}
113+
return ans;
114+
}
115+
}
116+
```
117+
TypeScript 代码:
118+
```TypeScript
119+
function exclusiveTime(n: number, logs: string[]): number[] {
120+
const ans = new Array<number>(n).fill(0)
121+
const stk = new Array<number>()
122+
let he = 0, ta = 0, cur = -1
123+
for (let log of logs) {
124+
const ss = log.split(":")
125+
const idx = Number(ss[0]), ts = Number(ss[2])
126+
if (ss[1] == "start") {
127+
if (he < ta) ans[stk[ta - 1]] += ts - cur
128+
stk[ta++] = idx
129+
cur = ts
130+
} else {
131+
const func = stk[--ta]
132+
ans[func] += ts - cur + 1
133+
cur = ts + 1
134+
}
135+
}
136+
return ans
137+
};
138+
```
139+
* 时间复杂度:$O(n)$
140+
* 空间复杂度:$O(n)$
141+
142+
---
143+
144+
### 最后
145+
146+
这是我们「刷穿 LeetCode」系列文章的第 `No.636` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
147+
148+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
149+
150+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
151+
152+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
153+

0 commit comments

Comments
 (0)