返回介绍

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

发布于 2024-06-17 01:04:41 字数 6420 浏览 0 评论 0 收藏 0

剑指 Offer II 113. 课程顺序

题目描述

现在总共有 numCourses 门课需要选,记为 0 到 numCourses-1

给定一个数组 prerequisites ,它的每一个元素 prerequisites[i] 表示两门课程之间的先修顺序。 例如 prerequisites[i] = [ai, bi] 表示想要学习课程 ai ,需要先完成课程 bi 。

请根据给出的总课程数  numCourses 和表示先修顺序的 prerequisites 得出一个可行的修课序列。

可能会有多个正确的顺序,只要任意返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

 

示例 1:

输入: numCourses = 2, prerequisites = [[1,0]] 
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
 因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

示例 3:

输入: numCourses = 1, prerequisites = [] 
输出: [0]
解释: 总共 1 门课,直接修第一门课就可。

 

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • ai != bi
  • prerequisites 中不存在重复元素

 

注意:本题与主站 210 题相同:https://leetcode.cn/problems/course-schedule-ii/

解法

方法一

class Solution:
  def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
    g = defaultdict(list)
    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])
    ans = []
    while q:
      i = q.popleft()
      ans.append(i)
      for j in g[i]:
        indeg[j] -= 1
        if indeg[j] == 0:
          q.append(j)
    return ans if len(ans) == numCourses else []
class Solution {
  public int[] findOrder(int numCourses, int[][] prerequisites) {
    List<Integer>[] g = new List[numCourses];
    Arrays.setAll(g, k -> new ArrayList<>());
    int[] indeg = new int[numCourses];
    for (var p : prerequisites) {
      int a = p[0], b = p[1];
      g[b].add(a);
      ++indeg[a];
    }
    Deque<Integer> q = new ArrayDeque<>();
    for (int i = 0; i < numCourses; ++i) {
      if (indeg[i] == 0) {
        q.offer(i);
      }
    }
    int[] ans = new int[numCourses];
    int cnt = 0;
    while (!q.isEmpty()) {
      int i = q.poll();
      ans[cnt++] = i;
      for (int j : g[i]) {
        if (--indeg[j] == 0) {
          q.offer(j);
        }
      }
    }
    return cnt == numCourses ? ans : new int[0];
  }
}
class Solution {
public:
  vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
    vector<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);
    vector<int> ans;
    while (!q.empty()) {
      int i = q.front();
      q.pop();
      ans.push_back(i);
      for (int j : g[i])
        if (--indeg[j] == 0) q.push(j);
    }
    return ans.size() == numCourses ? ans : vector<int>();
  }
};
func findOrder(numCourses int, prerequisites [][]int) []int {
  g := make([][]int, numCourses)
  indeg := make([]int, numCourses)
  for _, p := range prerequisites {
    a, b := p[0], p[1]
    g[b] = append(g[b], a)
    indeg[a]++
  }
  q := []int{}
  for i, v := range indeg {
    if v == 0 {
      q = append(q, i)
    }
  }
  ans := []int{}
  for len(q) > 0 {
    i := q[0]
    q = q[1:]
    ans = append(ans, i)
    for _, j := range g[i] {
      indeg[j]--
      if indeg[j] == 0 {
        q = append(q, j)
      }
    }
  }
  if len(ans) == numCourses {
    return ans
  }
  return []int{}
}
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) {
    g[b].push(a);
    ++indeg[a];
  }
  let q = [];
  for (let i = 0; i < numCourses; ++i) {
    if (!indeg[i]) {
      q.push(i);
    }
  }
  let ans = [];
  while (q.length) {
    const i = q.shift();
    ans.push(i);
    for (let j of g[i]) {
      if (--indeg[j] == 0) {
        q.push(j);
      }
    }
  }
  return ans.length == numCourses ? ans : [];
}
public class Solution {
  public int[] FindOrder(int numCourses, int[][] prerequisites) {
    var 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 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);
    }
    var ans = new int[numCourses];
    var 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);
      }
    }
    return cnt == numCourses ? ans : new int[0];
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文