diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/README.md" index c622ce03447e1..0e6084e03f84a 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/README.md" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/README.md" @@ -56,19 +56,27 @@ ## 解法 -### 方法一 +### 方法一:拓扑排序 + +拓扑排序的思路是,先统计每个节点的入度,然后从入度为 0 的节点开始,依次删除这些节点,同时更新与这些节点相连的节点的入度,直到所有节点都被删除。 + +这里使用队列来存储入度为 0 的节点,每次从队列中取出一个节点,将其加入结果数组中,然后遍历与这个节点相连的节点,将这些节点的入度减 1,如果减 1 后入度为 0,则将这些节点加入队列中。 + +最后判断结果数组的长度是否等于节点的个数,如果等于则返回结果数组,否则返回空数组。 + +时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点的个数和边的个数。 ```python class Solution: def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]: - g = defaultdict(list) + g = [[] for _ in range(numCourses)] indeg = [0] * numCourses for a, b in prerequisites: g[b].append(a) indeg[a] += 1 - q = deque([i for i, v in enumerate(indeg) if v == 0]) + q = deque(i for i, v in enumerate(indeg) if v == 0) ans = [] while q: i = q.popleft() @@ -117,7 +125,7 @@ class Solution { class Solution { public: vector findOrder(int numCourses, vector>& prerequisites) { - vector> g(numCourses); + vector g[numCourses]; vector indeg(numCourses); for (auto& p : prerequisites) { int a = p[0], b = p[1]; @@ -125,15 +133,21 @@ public: ++indeg[a]; } queue q; - for (int i = 0; i < numCourses; ++i) - if (indeg[i] == 0) q.push(i); + for (int i = 0; i < numCourses; ++i) { + if (indeg[i] == 0) { + q.push(i); + } + } vector ans; - while (!q.empty()) { + while (q.size()) { int i = q.front(); q.pop(); ans.push_back(i); - for (int j : g[i]) - if (--indeg[j] == 0) q.push(j); + for (int j : g[i]) { + if (--indeg[j] == 0) { + q.push(j); + } + } } return ans.size() == numCourses ? ans : vector(); } @@ -176,61 +190,55 @@ func findOrder(numCourses int, prerequisites [][]int) []int { ```ts function findOrder(numCourses: number, prerequisites: number[][]): number[] { - let g = Array.from({ length: numCourses }, () => []); - let indeg = new Array(numCourses).fill(0); - for (let [a, b] of prerequisites) { + const g: number[][] = Array.from({ length: numCourses }, () => []); + const indeg: number[] = Array(numCourses).fill(0); + for (const [a, b] of prerequisites) { g[b].push(a); ++indeg[a]; } - let q = []; - for (let i = 0; i < numCourses; ++i) { - if (!indeg[i]) { - q.push(i); - } - } - let ans = []; + const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1); + const ans: number[] = []; while (q.length) { - const i = q.shift(); + const i = q.pop()!; ans.push(i); - for (let j of g[i]) { - if (--indeg[j] == 0) { + for (const j of g[i]) { + if (--indeg[j] === 0) { q.push(j); } } } - return ans.length == numCourses ? ans : []; + return ans.length === numCourses ? ans : []; } ``` ```cs public class Solution { public int[] FindOrder(int numCourses, int[][] prerequisites) { - var g = new List[numCourses]; - for (int i = 0; i < numCourses; ++i) - { + List[] g = new List[numCourses]; + for (int i = 0; i < numCourses; i++) { g[i] = new List(); } - var indeg = new int[numCourses]; - foreach (var p in prerequisites) - { + int[] indeg = new int[numCourses]; + foreach (var p in prerequisites) { int a = p[0], b = p[1]; g[b].Add(a); ++indeg[a]; } - var q = new Queue(); - for (int i = 0; i < numCourses; ++i) - { - if (indeg[i] == 0) q.Enqueue(i); + Queue q = new Queue(); + for (int i = 0; i < numCourses; ++i) { + if (indeg[i] == 0) { + q.Enqueue(i); + } } - var ans = new int[numCourses]; - var cnt = 0; - while (q.Count > 0) - { + int[] ans = new int[numCourses]; + int cnt = 0; + while (q.Count > 0) { int i = q.Dequeue(); ans[cnt++] = i; - foreach (int j in g[i]) - { - if (--indeg[j] == 0) q.Enqueue(j); + foreach (int j in g[i]) { + if (--indeg[j] == 0) { + q.Enqueue(j); + } } } return cnt == numCourses ? ans : new int[0]; diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cpp" "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cpp" index ab3af7299602d..c64768219bc49 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cpp" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cpp" @@ -1,7 +1,7 @@ class Solution { public: vector findOrder(int numCourses, vector>& prerequisites) { - vector> g(numCourses); + vector g[numCourses]; vector indeg(numCourses); for (auto& p : prerequisites) { int a = p[0], b = p[1]; @@ -9,15 +9,21 @@ class Solution { ++indeg[a]; } queue q; - for (int i = 0; i < numCourses; ++i) - if (indeg[i] == 0) q.push(i); + for (int i = 0; i < numCourses; ++i) { + if (indeg[i] == 0) { + q.push(i); + } + } vector ans; - while (!q.empty()) { + while (q.size()) { int i = q.front(); q.pop(); ans.push_back(i); - for (int j : g[i]) - if (--indeg[j] == 0) q.push(j); + for (int j : g[i]) { + if (--indeg[j] == 0) { + q.push(j); + } + } } return ans.size() == numCourses ? ans : vector(); } diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cs" "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cs" index ba360f7a31921..93d29dfbbcfe0 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cs" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.cs" @@ -1,33 +1,32 @@ public class Solution { public int[] FindOrder(int numCourses, int[][] prerequisites) { - var g = new List[numCourses]; - for (int i = 0; i < numCourses; ++i) - { + List[] g = new List[numCourses]; + for (int i = 0; i < numCourses; i++) { g[i] = new List(); } - var indeg = new int[numCourses]; - foreach (var p in prerequisites) - { + int[] indeg = new int[numCourses]; + foreach (var p in prerequisites) { int a = p[0], b = p[1]; g[b].Add(a); ++indeg[a]; } - var q = new Queue(); - for (int i = 0; i < numCourses; ++i) - { - if (indeg[i] == 0) q.Enqueue(i); + Queue q = new Queue(); + for (int i = 0; i < numCourses; ++i) { + if (indeg[i] == 0) { + q.Enqueue(i); + } } - var ans = new int[numCourses]; - var cnt = 0; - while (q.Count > 0) - { + int[] ans = new int[numCourses]; + int cnt = 0; + while (q.Count > 0) { int i = q.Dequeue(); ans[cnt++] = i; - foreach (int j in g[i]) - { - if (--indeg[j] == 0) q.Enqueue(j); + foreach (int j in g[i]) { + if (--indeg[j] == 0) { + q.Enqueue(j); + } } } return cnt == numCourses ? ans : new int[0]; } -} +} \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.py" "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.py" index d043ce95948f7..3c822a41d210e 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.py" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.py" @@ -1,11 +1,11 @@ class Solution: def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]: - g = defaultdict(list) + g = [[] for _ in range(numCourses)] indeg = [0] * numCourses for a, b in prerequisites: g[b].append(a) indeg[a] += 1 - q = deque([i for i, v in enumerate(indeg) if v == 0]) + q = deque(i for i, v in enumerate(indeg) if v == 0) ans = [] while q: i = q.popleft() diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.ts" "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.ts" index ec8414f47176e..0567de23a377b 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.ts" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 113. \350\257\276\347\250\213\351\241\272\345\272\217/Solution.ts" @@ -1,25 +1,20 @@ function findOrder(numCourses: number, prerequisites: number[][]): number[] { - let g = Array.from({ length: numCourses }, () => []); - let indeg = new Array(numCourses).fill(0); - for (let [a, b] of prerequisites) { + const g: number[][] = Array.from({ length: numCourses }, () => []); + const indeg: number[] = Array(numCourses).fill(0); + for (const [a, b] of prerequisites) { g[b].push(a); ++indeg[a]; } - let q = []; - for (let i = 0; i < numCourses; ++i) { - if (!indeg[i]) { - q.push(i); - } - } - let ans = []; + const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1); + const ans: number[] = []; while (q.length) { - const i = q.shift(); + const i = q.pop()!; ans.push(i); - for (let j of g[i]) { - if (--indeg[j] == 0) { + for (const j of g[i]) { + if (--indeg[j] === 0) { q.push(j); } } } - return ans.length == numCourses ? ans : []; + return ans.length === numCourses ? ans : []; }