# Leetcode 207: Course Schedule

## There are a total of `numCourses`

courses you have to take, labeled from `0`

to `numCourses - 1`

. You are given an array `prerequisites`

where `prerequisites[i] = [ai, bi]`

indicates that you **must** take course `bi`

first if you want to take course `ai`

.

- For example, the pair
`[0, 1]`

, indicates that to take course`0`

you have to first take course`1`

.

Return `true`

if you can finish all courses. Otherwise, return `false`

.

**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.

**Constraints:**

`1 <= numCourses <= 2000`

`0 <= prerequisites.length <= 5000`

`prerequisites[i].length == 2`

`0 <= ai, bi < numCourses`

- All the pairs prerequisites[i] are
**unique**.

**Problem Analysis:**

After read the problem, we can know if we can finish courses, there must be no prerequisites loop cycle. As show in example 2.

So our task is to check whether some loop cycle happens.

It is a classic dfs problem.

**Solution**

`class Solution {`

public:

bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {

for (const auto& item : prerequisites)

data_[item.front()].insert(item.back());

vector<bool> visited(numCourses, false);

vector<bool> on_stack(numCourses, false);

for (int i = 0; i < numCourses; ++i) {

if (!visited[i]) {

if (isLoop(i, visited, on_stack)) return false;

}

}

return true;

}

bool isLoop(int index, vector<bool>& visited, vector<bool>& on_stack) {

visited[index] = true;

on_stack[index] = true;

auto it = data_.find(index);

if (it != data_.end()) {

for (const auto& item : it->second) {

if (!visited[item]) {

if (isLoop(item, visited, on_stack)) return true;

} else if (on_stack[item]) {

return true;

}

}

}

on_stack[index] = false;

return false;

}

private:

unordered_map<int, unordered_set<int>> data_;

};

time complexity is O(n)

Space complexity is O(n)