Skip to content

Commit

Permalink
feat: add solutions to lcof2 problem: No.113 (#2474)
Browse files Browse the repository at this point in the history
No.113.课程顺序
  • Loading branch information
yanglbme authored Mar 21, 2024
1 parent 311eb3e commit 174bc92
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 80 deletions.
88 changes: 48 additions & 40 deletions lcof2/剑指 Offer II 113. 课程顺序/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,27 @@

## 解法

### 方法一
### 方法一:拓扑排序

拓扑排序的思路是,先统计每个节点的入度,然后从入度为 0 的节点开始,依次删除这些节点,同时更新与这些节点相连的节点的入度,直到所有节点都被删除。

这里使用队列来存储入度为 0 的节点,每次从队列中取出一个节点,将其加入结果数组中,然后遍历与这个节点相连的节点,将这些节点的入度减 1,如果减 1 后入度为 0,则将这些节点加入队列中。

最后判断结果数组的长度是否等于节点的个数,如果等于则返回结果数组,否则返回空数组。

时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点的个数和边的个数。

<!-- tabs:start -->

```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()
Expand Down Expand Up @@ -117,23 +125,29 @@ class Solution {
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> g(numCourses);
vector<int> g[numCourses];
vector<int> indeg(numCourses);
for (auto& p : prerequisites) {
int a = p[0], b = p[1];
g[b].push_back(a);
++indeg[a];
}
queue<int> 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<int> 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<int>();
}
Expand Down Expand Up @@ -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<int>[numCourses];
for (int i = 0; i < numCourses; ++i)
{
List<int>[] g = new List<int>[numCourses];
for (int i = 0; i < numCourses; i++) {
g[i] = new List<int>();
}
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<int>();
for (int i = 0; i < numCourses; ++i)
{
if (indeg[i] == 0) q.Enqueue(i);
Queue<int> q = new Queue<int>();
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];
Expand Down
18 changes: 12 additions & 6 deletions lcof2/剑指 Offer II 113. 课程顺序/Solution.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> g(numCourses);
vector<int> g[numCourses];
vector<int> indeg(numCourses);
for (auto& p : prerequisites) {
int a = p[0], b = p[1];
g[b].push_back(a);
++indeg[a];
}
queue<int> 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<int> 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<int>();
}
Expand Down
35 changes: 17 additions & 18 deletions lcof2/剑指 Offer II 113. 课程顺序/Solution.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
public class Solution {
public int[] FindOrder(int numCourses, int[][] prerequisites) {
var g = new List<int>[numCourses];
for (int i = 0; i < numCourses; ++i)
{
List<int>[] g = new List<int>[numCourses];
for (int i = 0; i < numCourses; i++) {
g[i] = new List<int>();
}
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<int>();
for (int i = 0; i < numCourses; ++i)
{
if (indeg[i] == 0) q.Enqueue(i);
Queue<int> q = new Queue<int>();
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];
}
}
}
4 changes: 2 additions & 2 deletions lcof2/剑指 Offer II 113. 课程顺序/Solution.py
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
23 changes: 9 additions & 14 deletions lcof2/剑指 Offer II 113. 课程顺序/Solution.ts
Original file line number Diff line number Diff line change
@@ -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 : [];
}

0 comments on commit 174bc92

Please sign in to comment.