[LeetCode]Course Schedule II

来源:互联网 发布:软件打包工具 编辑:程序博客网 时间:2024/05/22 10:25
解题思路:
典型的拓扑排序。用DFS和BFS都可以实现
用DFS实现拓扑排序的教程 Topological Sort via DFS,我的实现就是参考这个教程
用BFS实现拓扑排序,参考wiki :BFS

方法一,DFS 实现:
注意一点:测试数据存在 环,所以在算法实现的时候,要添加一个hasCycle的标记。
判断环是否存在的逻辑:

用DFS找到edge上u的下一个顶点v,发现v已经explored。这个时候,如果v在环上,那么label[v]肯定没有设定,初始值为0,那么 label[v] < label_num;否则,label[v] > label_num, 凡是label已经被设置的顶点,其一定是找到了终点之后回溯。仔细想想。 

class Solution {public:    vector<bool> explored;    vector<int>  label;    int          label_num;    bool         hasCycle;    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {        label_num = numCourses-1;        explored.assign(numCourses, false);        label.assign(numCourses, 0);        hasCycle = false;        for (int i = 0; i < numCourses; ++i){            if (!explored[i]){                DFS(prerequisites, i);            }            if (hasCycle) break;        }        vector<int> ret;        if (!hasCycle){            ret.assign(numCourses, 0);            for (int i = 0 ; i < numCourses; ++i){                ret[label[i]] = i;            }        }        return ret;    }    void DFS(vector<pair<int, int> >& graph, int s){        explored[s] = true;        // TODO: explored edge        vector<pair<int, int> >::iterator it = graph.begin();        while(it != graph.end()){            if (it->second == s ){                if(!explored[it->first]){                    DFS(graph, it->first);                }else{                    if (label[it->first] < label_num){                        hasCycle = true;                    }                }            }             if (hasCycle)                return;            it++;        }        // mark label        label[s] = label_num;        label_num--;    }};

方法二,BFS实现:

前条件:计算inDegree数组,0 inDegree队列 queue, 拓扑排序数组sortedArray
不变式:从queue取出一个0入度顶点v,加入到sortedArray中, 从graph删除所有 edge of v, 同时相应的顶点inDegree[i]—1,如果这时候inDegree[i] == 0, 那么 i 加入queue
结束条件:queue为空,返回sortedArray,如果没有环的话。
临界条件:结束遍历,graph依然有edge,说明存在环

注意一点:对于容器的便利,尤其是需要erase的,最好都用iterator来,别用整型index  

class Solution {public:    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {        vector<int> sortedArray;        vector<int> inDegrees(numCourses);        queue<int> zeroIndegreeArray;        // compute indegree        for (int i = 0; i < prerequisites.size(); ++i){            inDegrees[prerequisites[i].first] ++;        }        for (int i = 0; i < numCourses; ++i){            if (inDegrees[i] == 0){                zeroIndegreeArray.push(i);            }        }        while(!zeroIndegreeArray.empty()){            int node = zeroIndegreeArray.front();            zeroIndegreeArray.pop();            sortedArray.push_back(node);            vector<pair<int, int> >::iterator it = prerequisites.begin();            while(it != prerequisites.end()){                if (it->second == node){                    int vex = it->first;                    it = prerequisites.erase(it);                    --inDegrees[vex];                    if (inDegrees[vex] == 0){                        zeroIndegreeArray.push(vex);                    }                }else{                    it++;                }            }        }        if (prerequisites.size() > 0){            return vector<int>();        }        return sortedArray;    }};



0 0
原创粉丝点击