LeetCode207. Course Schedule

题目来源:LeetCode207. 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.

For example: 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.

分析题意可以知道我们需要根据给定的课程数目,以及两两相对顺序来判断所有课程是否可以构成一个能依次进行的课程。
由此我们可以很容易联想到图论当中的拓扑排序,给定的两两相对顺序是图的边,给定的课程是图的点。若图能够拓扑排序,则返回yes,否则返回false。

具体代码如下:

struct graph{
    int vexs;
    int sides;
    vector<list<int>> arc;
    graph(int v = 0, int s = 0){
        vexs = v;
        sides = s;
        arc.resize(v);
    }
};


class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        graph G(numCourses,prerequisites.size());
        vector<int> ind(numCourses,0);
        for(vector<pair<int, int> >::iterator it = prerequisites.begin(); it != prerequisites.end(); it ++){
            G.arc[(*it).first].push_back((*it).second);
            ind[(*it).second]++;
        }
        int count = 0;
        stack<int> s;
        for(int i = 0; i < numCourses; i++){
            if(ind[i] == 0){
                count++;
                s.push(i);
                ind[s.top()] = -1;  // avoid to be accessed repeatedly
            }
        }
        while(!s.empty()){
            for(list<int>::iterator it = G.arc[s.top()].begin(); it != G.arc[s.top()].end(); it ++){
                ind[*it]--;
            }
            s.pop();
            for(int i = 0;i < numCourses; i++){
                if(ind[i] == 0){
                    count++;
                    s.push(i);
                    ind[s.top()] = -1;  // avoid to be accessed repeatedly
                }
            }
        }
        if(count == numCourses)return true;
        else return false;
    }

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值