Skip to content
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

207. Course Schedule #186

Open
Tcdian opened this issue May 30, 2020 · 1 comment
Open

207. Course Schedule #186

Tcdian opened this issue May 30, 2020 · 1 comment

Comments

@Tcdian
Copy link
Owner

Tcdian commented May 30, 2020

207. Course Schedule

你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]

给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?

Example 1

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0, and to take course 0 you should
             also have finished course 1. So it is impossible.

Note:

  • 输入的先决条件是由 边缘列表 表示的图形,而不是 邻接矩阵 。
  • 你可以假定输入的先决条件中没有重复的边。
  • 1 <= numCourses <= 10^5
@Tcdian
Copy link
Owner Author

Tcdian commented May 30, 2020

Solution

  • JavaScript Solution
const Status = {
    initial: 0,
    visiting: 1,
    visited: 2,
}

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function(numCourses, prerequisites) {
    const graph = Array.from(new Array(numCourses), () => []);
    for (let i = 0; i < prerequisites.length; i++) {
        const [course, preCourse] = prerequisites[i];
        graph[preCourse].push(course);
    }
    const statuses = new Array(numCourses).fill(Status.initial);
    for (let i = 0; i < numCourses; i++) {
        if (hasCycle(i)) {
            return false;
        }
    }
    return true;

    function hasCycle(course) {
        if (statuses[course] === Status.visited) {
            return false;
        }
        if (statuses[course] === Status.visiting) {
            return true;
        }
        statuses[course] = Status.visiting;
        const courses = graph[course];
        for (let i = 0; i < courses.length; i++) {
            if (hasCycle(courses[i])) {
                return true;
            }
        }
        statuses[course] = Status.visited;
        return false;
    }
};
  • TypeScript Solution
enum Status {
    initial,
    visiting,
    visited,
}

function canFinish(numCourses: number, prerequisites: number[][]): boolean {
    const graph: number[][] = Array.from(new Array(numCourses), () => []);
    for (let i = 0; i < prerequisites.length; i++) {
        const [course, preCourse] = prerequisites[i];
        graph[preCourse].push(course);
    }
    const statuses: Status[] = new Array(numCourses).fill(Status.initial);
    for (let i = 0; i < numCourses; i++) {
        if (hasCycle(i)) {
            return false;
        }
    }
    return true;

    function hasCycle(course: number): boolean {
        if (statuses[course] === Status.visited) {
            return false;
        }
        if (statuses[course] === Status.visiting) {
            return true;
        }
        statuses[course] = Status.visiting;
        const courses = graph[course];
        for (let i = 0; i < courses.length; i++) {
            if (hasCycle(courses[i])) {
                return true;
            }
        }
        statuses[course] = Status.visited;
        return false;
    }
};

@Tcdian Tcdian removed the Classic label Jul 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant