Labels

Tuesday, June 16, 2015

Course Schedule

There are a total of n courses you have to take, labeled from 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