Skip to content

Commit e55c110

Browse files
committed
Add: Add 2025/1/27
1 parent 7d86b0b commit e55c110

File tree

3 files changed

+150
-4
lines changed

3 files changed

+150
-4
lines changed

1462-Course Schedule IV/Note.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# 1462. Course Schedule IV
2+
3+
There are a total of `numCourses` courses you have to take, labeled from `0` to `numCourses - 1`.
4+
You are given an array `prerequisites` where `prerequisites[i] = [a_i, b_i]` indicates that
5+
you must take course `a_i` first if you want to take course `b_i`.
6+
7+
For example, the pair `[0, 1]` indicates that you have to take course `0` before you can take course `1`.
8+
Prerequisites can also be indirect.
9+
If course `a` is a prerequisite of course `b`,
10+
and course `b` is a prerequisite of course `c`, then course `a` is a prerequisite of course `c`.
11+
12+
You are also given an array `queries` where `queries[j] = [uj, vj]`.
13+
For the `j_th` query, you should answer whether course `u_j` is a prerequisite of course `v_j` or not.
14+
15+
Return a boolean array answer, where `answer[j]` is the answer to the `j_th` query.
16+
17+
## 基礎思路
18+
這題需要構建關聯表,然後查詢是否有關聯。我們可以把這題轉化成一個有向圖,然後查詢是否有路徑。
19+
在這題我將採取深度優先搜索的方式來解決這個問題。
20+
21+
## 解題步驟
22+
23+
### Step 1: 初始化圖,並將直接關聯的節點加入圖中
24+
25+
```typescript
26+
// 圖會是一個二維數組,用來記錄每個節點的關聯性
27+
const graph: number[][] = Array.from({ length: numCourses }, () => []);
28+
29+
// 先把直接關聯的節點加入圖中
30+
for (const [u, v] of prerequisites) {
31+
graph[u].push(v);
32+
}
33+
```
34+
35+
### Step 2: 深度優先搜索
36+
37+
```typescript
38+
// 定義可到達的節點
39+
const reachable = Array.from({ length: numCourses }, () => new Set<number>());
40+
41+
// 深度優先搜索
42+
const dfs = (node: number) => {
43+
for (const neighbor of graph[node]) {
44+
// 如果已經建構過這個節點的關聯性,則跳過
45+
if (reachable[node].has(neighbor)) {
46+
continue;
47+
}
48+
49+
// 新增節點到可到達的節點中
50+
reachable[node].add(neighbor);
51+
52+
// 遞迴搜索其鄰居
53+
dfs(neighbor);
54+
55+
// 新增鄰居的可到達節點到當前節點的可到達節點中
56+
for (const n of reachable[neighbor]) {
57+
reachable[node].add(n);
58+
}
59+
}
60+
};
61+
```
62+
63+
### Step 3: 遍歷所有節點,並進行深度優先搜索
64+
65+
```typescript
66+
for (let i = 0; i < numCourses; i++) {
67+
dfs(i);
68+
}
69+
```
70+
71+
### Step 4: 查詢是否有關聯
72+
73+
```typescript
74+
return queries.map(([u, v]) => reachable[u].has(v));
75+
```
76+
77+
## 時間複雜度
78+
- **建圖成本:**
79+
- 用鄰接表建圖的時間複雜度是 $O(m)$,這是所有預修課程所構成的邊的數量。
80+
81+
- **DFS 及可達性集合 (Union 操作):**
82+
- **DFS 遍歷的部分:** 每次從一個節點開始進行 DFS,在遍歷的過程中,每條邊最多被訪問一次,所以這部分的遍歷成本為 $O(m)$。
83+
- **更新集合的部分:** 每次進行集合合併操作時,可能需要將 $reachable[neighbor]$ 的所有節點合併到 $reachable[node]$。在最壞情況下,這個集合可能包含最多 $O(n)$ 節點。
84+
因此,每次合併的成本是 $O(n)$,而且每條邊的操作成本因此變為 $O(n)$。
85+
DFS 和集合合併操作的總成本是:
86+
$$
87+
O(n \cdot (n + m)) = O(n^2 + n \cdot m)
88+
$$
89+
因為我們需要對每個節點執行 DFS,總成本乘以 $n$,得到:
90+
$$
91+
O(n \cdot (n^2 + n \cdot m)) = O(n^3 + n^2 \cdot m)
92+
$$
93+
94+
- **查詢成本:**
95+
每次查詢 $reachable[u]$ 是否包含 $v$ 是 $O(1)$,對於 $q$ 個查詢,總成本是 $O(q)$。
96+
97+
> $O(n^3 + n^2 \cdot m + m + q) \approx O(n^3 + n^2 \cdot m)$
98+
99+
## 空間複雜度
100+
101+
- **鄰接表儲存空間:** $O(n + m)$。
102+
- **Reachable 集合儲存空間:** $O(n^2)$,因為每個節點最多需要儲存 $n$ 個可達節點。
103+
- **遞歸堆疊:** 最深可能達到 $O(n)$。
104+
105+
> $O(n^2 + m)$

1462-Course Schedule IV/answer.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
function checkIfPrerequisite(
2+
numCourses: number,
3+
prerequisites: number[][],
4+
queries: number[][]
5+
): boolean[] {
6+
// Initialize the graph
7+
const graph: number[][] = Array.from({ length: numCourses }, () => []);
8+
9+
// Construct the graph with the prerequisite dependencies
10+
for (const [u, v] of prerequisites) {
11+
graph[u].push(v);
12+
}
13+
14+
// Define the reachable set of each node
15+
const reachable = Array.from({ length: numCourses }, () => new Set<number>());
16+
17+
// Use DFS to calculate the reachable set of each node
18+
const dfs = (node: number) => {
19+
for (const neighbor of graph[node]) {
20+
// Skip if the neighbor is already reachable
21+
if (reachable[node].has(neighbor)) {
22+
continue;
23+
}
24+
25+
// Add the neighbor to the reachable set
26+
reachable[node].add(neighbor);
27+
28+
// Recursively call the DFS
29+
dfs(neighbor);
30+
31+
// Add the reachable set of the neighbor to the reachable set of the node
32+
for (const n of reachable[neighbor]) {
33+
reachable[node].add(n);
34+
}
35+
}
36+
};
37+
38+
// Find the reachable set of each node
39+
for (let i = 0; i < numCourses; i++) {
40+
dfs(i);
41+
}
42+
43+
// Return the result
44+
return queries.map(([u, v]) => reachable[u].has(v));
45+
}

2127-Maximum Employees to Be Invited to a Meeting/Note.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ return the maximum number of employees that can be invited to the meeting.
2727
2828
## 解題步驟
2929

30-
以下步驟對應到主要程式邏輯,並附上重點程式片段說明。
31-
32-
---
33-
3430
### Step 1: 找出圖中最大的迴圈長度
3531

3632
```typescript

0 commit comments

Comments
 (0)