Skip to content

feat: add solutions to lcof2 problem: No.113 #2474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 : [];
}
Loading