[leetcode#207] Course Schedule

Source: Internet
Author: User

problem:

There is a total of n courses you have to take, labeled from 0 to n - 1 .

Some courses May has 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, are it possible for your to finish all courses?

For example:

2, [[1,0]]

There is a total of 2 courses to take. To take course 1 should has finished course 0. So it is possible.

2, [[1,0],[0,1]]

There is a total of 2 courses to take. To take course 1 should has finished course 0, and to take course 0 you should also has finished course 1. So it is impossible.

Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more on how a graph is represented.

Analysis:

reference:http://www.programcreek.com/2014/05/leetcode-course-schedule-java/The idea behind ThisProblem is isn't hard, we can treat it as a graph. The problem is to detectifThere is a circle exist. Since the degrees of a node ' s out/in edges could is greatly different, We should consider clear all case.Initial wrong Idea:take advantage of the Queue, we use BFS method to solve Thisproblem through following Pattern:step1: Scan The prerequisites matrix, to identify out of the courses that does does have prerequisites. and add them into Queue.step2: Pop A course out, and unlock all courses based on it as prerequisite, and add all of the them into queue. Step3:when the queue is empty, check the count of poped courses. To decideifAll courses could is studied through certain order. Solution: Public BooleanCanfinish (intNumcourses,int[] Prerequisites) {        if(Prerequisites = =NULL)            Throw NewIllegalArgumentException ("Invalid Prerequisites Matrix"); intm =prerequisites.length; Boolean[] used =New Boolean[M]; intCount = 0; if(numcourses = = 0 | | m = = 0)            return true; Queue<Integer> queue =NewLinkedlist<integer> ();  for(inti = 0; I < m; i++) {            BooleanNo_pre =true;  for(intj = 0; J < M; J + +) {No_pre= No_pre && (prerequisites[i][j] = = 0); }            if(no_pre) {queue.offer (i); }        }        if(queue.size () = = 0)return false;  while(!Queue.isempty ()) {            intCur =Queue.poll (); Used[cur]=true; Count++;        Unlockcourse (Prerequisites, queue, cur, used); }        returnCount = =numcourses; }         Public voidUnlockcourse (int[] Prerequisites, queue<integer> Queue,intCurBoolean[] used) {        intm =prerequisites.length;  for(inti = 0; I < m; i++) {            //search through BFS must tag the visited element            if(Prerequisites[i][cur] = = 1 && used[i] = =false) Queue.offer (i); }} The above solution is wrong forfollowing reasons:1. The graph is represented in edges rather than adjacency matrix.2. A course may has more than one prerequisites!!! You can ' t unlock all courses for a unlocked course. while(!Queue.isempty ()) {    intCur =Queue.poll (); Used[cur]=true; Count++; Unlockcourse (Prerequisites, queue, cur, used);} A fix:the above actually has laid a very good foundation forus to fix. The same idea:use a queue forRecording unlocked courses, when a course poped out from the queue, we increase the count of unlocked course. Besides the queue, we also take advantage of a counter array, which records the left prerequisites fora course. Only if the prerequisites count of a course equal to0, we treat it as an unlocked course and add it into the queue. Step1:count The Prerequisites forEach course.int[] Pre_counter =New int[numcourses];intLen =prerequisites.length; for(inti = 0; i < Len; i++) {pre_counter[prerequisites[i][0]]++;} Step2: Put courses that has no prerequisites into the queue. for(inti = 0; i < numcourses; i++) {    if(Pre_counter[i] = = 0) Queue.offer (i);} Step3: Unlock courses through unlocked courses. while(!Queue.isempty ()) {    intCur =Queue.poll (); Count++;  for(inti = 0; i < Len; i++) {        //Note the logic here, must [i][1] = = cur, guarantee repeately add in to queue        if(Prerequisites[i][1] = =cur) {pre_counter[prerequisites[i][0]]--; if(Pre_counter[prerequisites[i][0]] = = 0) Queue.offer (prerequisites[i][0]); }}}}logic pitfall:i has made following Logic errors, which result in Infinite loop. if(Prerequisites[i][1] = =cur) {pre_counter[prerequisites[i][0]]--;}if(Pre_counter[prerequisites[i][0]] = = 0) {Queue.offer (prerequisites[i][0]);} The most common mistakes on using BFS is to revisit node and add it into the queue again. The mistake I has made at here is a good example.  for(inti = 0; i < Len; i++) {    ...} This would cause us to revisit pre_counter[prerequisites[i][0]] time and time, and keep on add prerequisites[i][0] to our queue. Thus we usually use a visited arrays to indicate, a course has alredy been unlocked and visisted. But for  ThisProblem, we can DoIt's in a and simple . Fix Method: for(inti = 0; i < Len; i++) {    if(Prerequisites[i][1] = =cur) {pre_counter[prerequisites[i][0]]--; if(Pre_counter[prerequisites[i][0]] = = 0) Queue.offer (prerequisites[i][0]); }}why It works?First , let us assume the same cur would only be poped once before enter the loop. for(inti = 0; i < numcourses; i++) {    if(Pre_counter[i] = = 0) Queue.offer (i);} only for"prerequisites[i][1] = = cur"and it just solved a unlock courses (we can say its the last prerequisites course). We add the course into queue.if(Pre_counter[prerequisites[i][0]] = = 0) Queue.offer (prerequisites[i][0]); Which means, only when a course is just unlocked, we add it into the queue. No other times of adding a element into the queue. Note:the cur would only is poped out, since we add it only once. Another fix method. Use a visited array.Boolean[] visited =New Boolean[numcourses]; while(!Queue.isempty ()) {    intCur =Queue.poll (); Visited[cur]=true; Count++;  for(inti = 0; i < Len; i++) {    //Note the logic here, must [i][1] = = cur, guarantee repeately add in to queue        if(Prerequisites[i][1] = =cur) pre_counter[prerequisites[i][0]]--; if(pre_counter[prerequisites[i][0] [= 0 && visited[prerequisites[i][0]] = =false) Queue.offer (prerequisites[i][0]); }}even though This  Thiswould solve Infinte loop problem, but it still could exceed time if the size of courses is large. Then reason are that:we keep on visit on all"Pre_counter[prerequisites[i][0]]"no matterif(Prerequisites[i][1] = =cur) This method is rude and wrong, we shouldTryTo avoid uncessary check.if(Prerequisites[i][1] = =cur) {pre_counter[prerequisites[i][0]]--; if(pre_counter[prerequisites[i][0] [= 0 && visited[prerequisites[i][0]] = =false) Queue.offer (prerequisites[i][0]);}

Solution:

 Public classSolution { Public BooleanCanfinish (intNumcourses,int[] Prerequisites) {        if(Prerequisites = =NULL)            Throw NewIllegalArgumentException ("The prerequisites matrix is not valid"); intLen =prerequisites.length; Boolean[] visited =New Boolean[numcourses]; if(numcourses = = 0 | | len = 0)            return true; int[] Pre_counter =New int[numcourses]; intCount = 0; Queue<Integer> queue =NewLinkedlist<integer> ();  for(inti = 0; i < Len; i++) {pre_counter[prerequisites[i][0]]++; }         for(inti = 0; i < numcourses; i++) {            if(Pre_counter[i] = = 0) {queue.offer (i); }        }         while(!Queue.isempty ()) {            intCur =Queue.poll (); Visited[cur]=true; Count++;  for(inti = 0; i < Len; i++) {                //Note the logic here, must [i][1] = = cur, guarantee repeately add in to queue                if(Prerequisites[i][1] = =cur) {pre_counter[prerequisites[i][0]]--; if(pre_counter[prerequisites[i][0] [= 0 && visited[prerequisites[i][0]] = =false) Queue.offer (prerequisites[i][0]); }                        }        }        returnCount = =numcourses; }}

[leetcode#207] Course Schedule

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.