Skip to content

Commit bd2ea84

Browse files
authored
Merge branch 'doocs:main' into main
2 parents e85d579 + 174bc92 commit bd2ea84

File tree

40 files changed

+649
-167
lines changed

40 files changed

+649
-167
lines changed

lcof2/剑指 Offer II 113. 课程顺序/README.md

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,27 @@
5656

5757
## 解法
5858

59-
### 方法一
59+
### 方法一:拓扑排序
60+
61+
拓扑排序的思路是,先统计每个节点的入度,然后从入度为 0 的节点开始,依次删除这些节点,同时更新与这些节点相连的节点的入度,直到所有节点都被删除。
62+
63+
这里使用队列来存储入度为 0 的节点,每次从队列中取出一个节点,将其加入结果数组中,然后遍历与这个节点相连的节点,将这些节点的入度减 1,如果减 1 后入度为 0,则将这些节点加入队列中。
64+
65+
最后判断结果数组的长度是否等于节点的个数,如果等于则返回结果数组,否则返回空数组。
66+
67+
时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点的个数和边的个数。
6068

6169
<!-- tabs:start -->
6270

6371
```python
6472
class Solution:
6573
def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
66-
g = defaultdict(list)
74+
g = [[] for _ in range(numCourses)]
6775
indeg = [0] * numCourses
6876
for a, b in prerequisites:
6977
g[b].append(a)
7078
indeg[a] += 1
71-
q = deque([i for i, v in enumerate(indeg) if v == 0])
79+
q = deque(i for i, v in enumerate(indeg) if v == 0)
7280
ans = []
7381
while q:
7482
i = q.popleft()
@@ -117,23 +125,29 @@ class Solution {
117125
class Solution {
118126
public:
119127
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
120-
vector<vector<int>> g(numCourses);
128+
vector<int> g[numCourses];
121129
vector<int> indeg(numCourses);
122130
for (auto& p : prerequisites) {
123131
int a = p[0], b = p[1];
124132
g[b].push_back(a);
125133
++indeg[a];
126134
}
127135
queue<int> q;
128-
for (int i = 0; i < numCourses; ++i)
129-
if (indeg[i] == 0) q.push(i);
136+
for (int i = 0; i < numCourses; ++i) {
137+
if (indeg[i] == 0) {
138+
q.push(i);
139+
}
140+
}
130141
vector<int> ans;
131-
while (!q.empty()) {
142+
while (q.size()) {
132143
int i = q.front();
133144
q.pop();
134145
ans.push_back(i);
135-
for (int j : g[i])
136-
if (--indeg[j] == 0) q.push(j);
146+
for (int j : g[i]) {
147+
if (--indeg[j] == 0) {
148+
q.push(j);
149+
}
150+
}
137151
}
138152
return ans.size() == numCourses ? ans : vector<int>();
139153
}
@@ -176,61 +190,55 @@ func findOrder(numCourses int, prerequisites [][]int) []int {
176190

177191
```ts
178192
function findOrder(numCourses: number, prerequisites: number[][]): number[] {
179-
let g = Array.from({ length: numCourses }, () => []);
180-
let indeg = new Array(numCourses).fill(0);
181-
for (let [a, b] of prerequisites) {
193+
const g: number[][] = Array.from({ length: numCourses }, () => []);
194+
const indeg: number[] = Array(numCourses).fill(0);
195+
for (const [a, b] of prerequisites) {
182196
g[b].push(a);
183197
++indeg[a];
184198
}
185-
let q = [];
186-
for (let i = 0; i < numCourses; ++i) {
187-
if (!indeg[i]) {
188-
q.push(i);
189-
}
190-
}
191-
let ans = [];
199+
const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1);
200+
const ans: number[] = [];
192201
while (q.length) {
193-
const i = q.shift();
202+
const i = q.pop()!;
194203
ans.push(i);
195-
for (let j of g[i]) {
196-
if (--indeg[j] == 0) {
204+
for (const j of g[i]) {
205+
if (--indeg[j] === 0) {
197206
q.push(j);
198207
}
199208
}
200209
}
201-
return ans.length == numCourses ? ans : [];
210+
return ans.length === numCourses ? ans : [];
202211
}
203212
```
204213

205214
```cs
206215
public class Solution {
207216
public int[] FindOrder(int numCourses, int[][] prerequisites) {
208-
var g = new List<int>[numCourses];
209-
for (int i = 0; i < numCourses; ++i)
210-
{
217+
List<int>[] g = new List<int>[numCourses];
218+
for (int i = 0; i < numCourses; i++) {
211219
g[i] = new List<int>();
212220
}
213-
var indeg = new int[numCourses];
214-
foreach (var p in prerequisites)
215-
{
221+
int[] indeg = new int[numCourses];
222+
foreach (var p in prerequisites) {
216223
int a = p[0], b = p[1];
217224
g[b].Add(a);
218225
++indeg[a];
219226
}
220-
var q = new Queue<int>();
221-
for (int i = 0; i < numCourses; ++i)
222-
{
223-
if (indeg[i] == 0) q.Enqueue(i);
227+
Queue<int> q = new Queue<int>();
228+
for (int i = 0; i < numCourses; ++i) {
229+
if (indeg[i] == 0) {
230+
q.Enqueue(i);
231+
}
224232
}
225-
var ans = new int[numCourses];
226-
var cnt = 0;
227-
while (q.Count > 0)
228-
{
233+
int[] ans = new int[numCourses];
234+
int cnt = 0;
235+
while (q.Count > 0) {
229236
int i = q.Dequeue();
230237
ans[cnt++] = i;
231-
foreach (int j in g[i])
232-
{
233-
if (--indeg[j] == 0) q.Enqueue(j);
238+
foreach (int j in g[i]) {
239+
if (--indeg[j] == 0) {
240+
q.Enqueue(j);
241+
}
234242
}
235243
}
236244
return cnt == numCourses ? ans : new int[0];

lcof2/剑指 Offer II 113. 课程顺序/Solution.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
class Solution {
22
public:
33
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
4-
vector<vector<int>> g(numCourses);
4+
vector<int> g[numCourses];
55
vector<int> indeg(numCourses);
66
for (auto& p : prerequisites) {
77
int a = p[0], b = p[1];
88
g[b].push_back(a);
99
++indeg[a];
1010
}
1111
queue<int> q;
12-
for (int i = 0; i < numCourses; ++i)
13-
if (indeg[i] == 0) q.push(i);
12+
for (int i = 0; i < numCourses; ++i) {
13+
if (indeg[i] == 0) {
14+
q.push(i);
15+
}
16+
}
1417
vector<int> ans;
15-
while (!q.empty()) {
18+
while (q.size()) {
1619
int i = q.front();
1720
q.pop();
1821
ans.push_back(i);
19-
for (int j : g[i])
20-
if (--indeg[j] == 0) q.push(j);
22+
for (int j : g[i]) {
23+
if (--indeg[j] == 0) {
24+
q.push(j);
25+
}
26+
}
2127
}
2228
return ans.size() == numCourses ? ans : vector<int>();
2329
}
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,32 @@
11
public class Solution {
22
public int[] FindOrder(int numCourses, int[][] prerequisites) {
3-
var g = new List<int>[numCourses];
4-
for (int i = 0; i < numCourses; ++i)
5-
{
3+
List<int>[] g = new List<int>[numCourses];
4+
for (int i = 0; i < numCourses; i++) {
65
g[i] = new List<int>();
76
}
8-
var indeg = new int[numCourses];
9-
foreach (var p in prerequisites)
10-
{
7+
int[] indeg = new int[numCourses];
8+
foreach (var p in prerequisites) {
119
int a = p[0], b = p[1];
1210
g[b].Add(a);
1311
++indeg[a];
1412
}
15-
var q = new Queue<int>();
16-
for (int i = 0; i < numCourses; ++i)
17-
{
18-
if (indeg[i] == 0) q.Enqueue(i);
13+
Queue<int> q = new Queue<int>();
14+
for (int i = 0; i < numCourses; ++i) {
15+
if (indeg[i] == 0) {
16+
q.Enqueue(i);
17+
}
1918
}
20-
var ans = new int[numCourses];
21-
var cnt = 0;
22-
while (q.Count > 0)
23-
{
19+
int[] ans = new int[numCourses];
20+
int cnt = 0;
21+
while (q.Count > 0) {
2422
int i = q.Dequeue();
2523
ans[cnt++] = i;
26-
foreach (int j in g[i])
27-
{
28-
if (--indeg[j] == 0) q.Enqueue(j);
24+
foreach (int j in g[i]) {
25+
if (--indeg[j] == 0) {
26+
q.Enqueue(j);
27+
}
2928
}
3029
}
3130
return cnt == numCourses ? ans : new int[0];
3231
}
33-
}
32+
}

lcof2/剑指 Offer II 113. 课程顺序/Solution.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
class Solution:
22
def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
3-
g = defaultdict(list)
3+
g = [[] for _ in range(numCourses)]
44
indeg = [0] * numCourses
55
for a, b in prerequisites:
66
g[b].append(a)
77
indeg[a] += 1
8-
q = deque([i for i, v in enumerate(indeg) if v == 0])
8+
q = deque(i for i, v in enumerate(indeg) if v == 0)
99
ans = []
1010
while q:
1111
i = q.popleft()
Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
function findOrder(numCourses: number, prerequisites: number[][]): number[] {
2-
let g = Array.from({ length: numCourses }, () => []);
3-
let indeg = new Array(numCourses).fill(0);
4-
for (let [a, b] of prerequisites) {
2+
const g: number[][] = Array.from({ length: numCourses }, () => []);
3+
const indeg: number[] = Array(numCourses).fill(0);
4+
for (const [a, b] of prerequisites) {
55
g[b].push(a);
66
++indeg[a];
77
}
8-
let q = [];
9-
for (let i = 0; i < numCourses; ++i) {
10-
if (!indeg[i]) {
11-
q.push(i);
12-
}
13-
}
14-
let ans = [];
8+
const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1);
9+
const ans: number[] = [];
1510
while (q.length) {
16-
const i = q.shift();
11+
const i = q.pop()!;
1712
ans.push(i);
18-
for (let j of g[i]) {
19-
if (--indeg[j] == 0) {
13+
for (const j of g[i]) {
14+
if (--indeg[j] === 0) {
2015
q.push(j);
2116
}
2217
}
2318
}
24-
return ans.length == numCourses ? ans : [];
19+
return ans.length === numCourses ? ans : [];
2520
}

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
black==24.2.0
1+
black==24.3.0
22
Requests==2.31.0

solution/3000-3099/3060.User Activities within Time Bounds/README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# [3060. User Activities within Time Bounds](https://leetcode.cn/problems/user-activities-within-time-bounds)
1+
# [3060. 时间范围内的用户活动](https://leetcode.cn/problems/user-activities-within-time-bounds)
22

33
[English Version](/solution/3000-3099/3060.User%20Activities%20within%20Time%20Bounds/README_EN.md)
44

@@ -8,7 +8,7 @@
88

99
<!-- 这里写题目描述 -->
1010

11-
<p>Table: <code>Sessions</code></p>
11+
<p>表:<code>Sessions</code></p>
1212

1313
<pre>
1414
+---------------+----------+
@@ -20,23 +20,24 @@
2020
| session_id | int |
2121
| session_type | enum |
2222
+---------------+----------+
23-
session_id is column of unique values for this table.
24-
session_type is an ENUM (category) type of (Viewer, Streamer).
25-
This table contains user id, session start, session end, session id and session type.
23+
session_id 是这张表中有不同值的列。
24+
session_type 是 (Viewer, Streamer) 的一个 ENUM (category) 类型。
25+
这张表包含 user id, session start, session end, session id session 类型。
2626
</pre>
2727

28-
<p>Write a solution to find the the <strong>users</strong> who have had <strong>at least one</strong> <strong>consecutive session</strong> of the <strong>same</strong> type (either &#39;<strong>Viewer</strong>&#39; or &#39;<strong>Streamer</strong>&#39;) with a <strong>maximum</strong> gap of <code>12</code> hours <strong>between</strong> sessions.</p>
28+
<p>编写一个解决方案,以查找 <strong>至少有一个相同</strong> 类型的 <strong>连续会话</strong>(无论是“<strong>Viewer</strong>”还是“<strong>Streamer</strong>”)的 <strong>用户</strong>,会话 <strong>之间</strong><strong>最大</strong> 间隔为 <code>12</code> 小时。</p>
2929

30-
<p>Return <em>the result table ordered by </em><code>user_id</code><em> in <b>ascending</b> order.</em></p>
30+
<p>返回结果表,以<em>&nbsp;</em><code>user_id</code><em>&nbsp;<strong>升序</strong> 排序。</em></p>
3131

32-
<p>The result format is in the following example.</p>
32+
<p>结果格式如下所述。</p>
3333

3434
<p>&nbsp;</p>
35-
<p><strong class="example">Example:</strong></p>
35+
36+
<p><strong class="example">示例:</strong></p>
3637

3738
<pre>
38-
<strong>Input:</strong>
39-
Sessions table:
39+
<strong>输入:</strong>
40+
Sessions :
4041
+---------+---------------------+---------------------+------------+--------------+
4142
| user_id | session_start | session_end | session_id | session_type |
4243
+---------+---------------------+---------------------+------------+--------------+
@@ -52,18 +53,18 @@ Sessions table:
5253
| 103 | 2023-11-02 20:00:00 | 2023-11-02 23:00:00 | 10 | Viewer |
5354
| 103 | 2023-11-03 09:00:00 | 2023-11-03 10:00:00 | 11 | Viewer |
5455
+---------+---------------------+---------------------+------------+--------------+
55-
<strong>Output:</strong>
56+
<strong>输出:</strong>
5657
+---------+
5758
| user_id |
5859
+---------+
5960
| 102 |
6061
| 103 |
6162
+---------+
62-
<strong>Explanation:</strong>
63-
- User ID 101 will not be included in the final output as they do not have any consecutive sessions of the same session type.
64-
- User ID 102 will be included in the final output as they had two viewer sessions with session IDs 3 and 4, respectively, and the time gap between them was less than 12 hours.
65-
- User ID 103 participated in two viewer sessions with a gap of less than 12 hours between them, identified by session IDs 10 and 11. Therefore, user 103 will be included in the final output.
66-
Output table is ordered by user_id in increasing order.
63+
<strong>解释:</strong>
64+
- 用户 ID 101 将不会包含在最终输出中,因为他们没有相同会话类型的连续回话。
65+
- 用户 ID 102 将会包含在最终输出中,因为他们分别有两个 session ID 为 3 和 4 的 viewer 会话,并且时间间隔在 12 小时内。
66+
- 用户 ID 103 参与了两次 viewer 会话,间隔不到 12 小时,会话 ID 为 10 11。因此,用户 103 将会被包含在最终输出中。
67+
输出表根据 user_id 升序排列。
6768
</pre>
6869

6970
## 解法

solution/3000-3099/3063.Linked List Frequency/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<!-- 这里写题目描述 -->
1010

11-
<p>给定包含 <code>k</code> 个&nbsp;<strong>不同&nbsp;</strong>元素的链表的&nbsp;<code>head</code>&nbsp;节点,创建一个长度为&nbsp;<code>k</code>&nbsp;的链表,包含给定链表中每个 <strong>不同元素</strong> <strong>任何顺序</strong> 出现的 <span data-keyword="frequency-linkedlist">频率</span>&nbsp;。返回这个链表的头节点。</p>
11+
<p>给定包含 <code>k</code> 个&nbsp;<strong>不同&nbsp;</strong>元素的链表的&nbsp;<code>head</code>&nbsp;节点,创建一个长度为&nbsp;<code>k</code>&nbsp;的链表, <strong>任何顺序</strong> 返回链表中所有 <strong>不同元素</strong> 出现的 <strong>频率</strong>。返回这个链表的头节点。</p>
1212

1313
<p>&nbsp;</p>
1414

0 commit comments

Comments
 (0)