0
to n - 1
.Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair:
[0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]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.
Naive Thinking: The description leads to a topological sort solution. But to execute a topological sort is not easy. If I directly use the 2D array on each iteration, I need to go though all 2D vectors. That's definitely not a good run time. The input 2D array needs to be preprocessed before implementing topological sort on it. After several trial, I find out that use a extra Course object with both prerequisite and advanced course attributes sounds.
public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
boolean exit = true;
List<Course> courses = new ArrayList<Course>();
Queue<Course> zero_pre_courses = new LinkedList<Course>();
// initialize courses list
for(int i = 0;i < numCourses;i++) courses.add(new Course(i));
// read in course prerequisite relationship
for(int i = 0;i < prerequisites.length;i++){
courses.get(prerequisites[i][0]).advanced.add(prerequisites[i][1]);
courses.get(prerequisites[i][1]).prerequisite.add(prerequisites[i][0]);
}
// group all zero prerequisite courses
for(int i = 0;i < numCourses;i++)
if(courses.get(i).prerequisite.isEmpty()) zero_pre_courses.add(courses.get(i));
// topological sort
while(!zero_pre_courses.isEmpty()){
Course course = zero_pre_courses.poll();
Iterator<Integer> iter = course.advanced.iterator();
while(iter.hasNext()){
int advancedCourseLabel = (int)iter.next();
Course advancedCourse = courses.get(advancedCourseLabel);
advancedCourse.prerequisite.remove(course.label);
if(advancedCourse.prerequisite.isEmpty()) zero_pre_courses.add(advancedCourse);
}
course.label = -1; // set label to -1 as the course is took
}
// check if all courses are took
for(int i = 0;i < numCourses;i++)
if(courses.get(i).label!=-1) exit = false;
return exit;
}
class Course{
Set<Integer> prerequisite;
Set<Integer> advanced;
int label;
Course(int l){
label = l;
prerequisite = new HashSet<Integer>();
advanced = new HashSet<Integer>();
}
}
}
No comments:
Post a Comment