210. Course Schedule II

2021-02-09  本文已影响0人  jluemmmm

课程选修问题,在修一些课程之前需要完成其他课程的学习,如果按照先决条件,可以完成所有课程的学习,返回可能的学习顺序。如果不能完成所有课程的学习,返回空数组。

图的两种表示方法:邻接矩阵与邻接表。

输入: 需要完成的课程数
输出:先决条件数组,[[3,1],[3,2]] 比如在完成课程 3 之前必须先完成课程 1 和 课程 2

BFS

思路:将先决条件转换成邻接表,将入度为0的课程依次入队,开始BFS,然后将后学的课程入度减1,再将入度为0的课程入队进行学习,直到所有课程学完为止。

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {number[]}
 */
var findOrder = function(numCourses, prerequisites) {
  const inDegress = Array(numCourses).fill(0)
  const res = []
  const G = Array(numCourses).fill(0).map(_ => [])
  
  for(let e of prerequisites) {
    G[e[1]].push(e[0])
    inDegress[e[0]]++
  }
  
  while(res.length < numCourses) {
    let hasCycle = true
    for (let i = 0; i < numCourses; i++) {
      if(inDegress[i] === 0) {
        res.push(i)
        inDegress[i] = -1
        hasCycle = false
        
        for(let w of G[i]) {
          inDegress[w]--
        }
      }
    }
    if(hasCycle) return []
  }
  return res
};

DFS

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {number[]}
 */

var findOrder = function(numCourses, prerequisites) {
    let stack = []
    let visited = Array(numCourses).fill(0)
    let hasCycle = false
    let G = Array(numCourses).fill(0).map(_ => [])
    
    for(let e of prerequisites) {
        G[e[1]].push(e[0])
    }
    for (let i = 0; i < numCourses && !hasCycle; i++) {
        if(!visited[i]) {
            dfs(i)
        }
        if(hasCycle) return []
    }
    return stack.reverse()
    
    
    function dfs(u) {
        visited[u] = 1
        for(let w of G[u]) {
            if(visited[w] === 0) {
                dfs(w)
                if(hasCycle) return
            } else if(visited[w] === 1){
                hasCycle = true
                return
            }
        }
        visited[u] = 2
        stack.push(u)
    }
};
上一篇下一篇

猜你喜欢

热点阅读