207.Course Schedule课程安排

qlmx
qlmx
qlmx
50
文章
2
评论
2020年2月15日00:18:01 评论 886阅读9分33秒

207. Course Schedule(课程安排)

1 问题描述

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?

已知有n个课程,标记从0至n-1,课程之间是有依赖关系的,例如希望完成0课程,可能需要先完成1课程。已知n个课程的依赖关系,求是否可以将n个课程全部完成。

Example 1:

Input: 2, [[1,0]] 
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 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.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

2 思路

  • 使用深度优先遍历:对输入进行分析,原始问题可以转换为有向图问题,当有向图无环时返回True,当有向图有环时返回False
  • 使用宽度优先遍历:只将入度为0的点添加至队列。当完成一个顶点的搜索(从队 列取出),它指向的所有顶点入度都减1,若此时某顶点入度为0则添加至队列,若完 成宽度搜索后,所有的点入度都为0,则图无环,否则有环。

3 C++实现

  • 图的实现
struct GraphNode{
    int label;
    std::vector<GraphNode *> neighbors;
    GraphNode(int x) : label(x) {};
};
  • 方法一:深度优先遍历
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<GraphNode *> graph;
        vector<int> visit;
        //创建图
        for(int i=0; i<numCourses; i++) {
            graph.push_back(new GraphNode(i));
            visit.push_back(-1);
        }

        //连接图
        for(int i=0; i<prerequisites.size(); i++) {
            GraphNode* begin = graph[prerequisites[i].second];
            GraphNode* end = graph[prerequisites[i].first];
            begin->neighbors.push_back(end);
        }

        //遍历
        for(int i=0; i<graph.size(); i++) {
            if(visit[i] == -1 && !DFS_graph(graph[i], visit))
                return false;
        }
        //回收内存
        for(int i=0; i<graph.size(); i++) {
            delete graph[i];
        }

        return true;
    }

private:
    bool DFS_graph(GraphNode *node, vector<int> &visit) {
        //节点访问控制,-1表示没有访问,0表示正在访问,1表示访问完成
        visit[node->label] = 0;
        for(int i=0; i<node->neighbors.size(); i++) {
            if(visit[node->neighbors[i]->label] == -1) {
                if(DFS_graph(node->neighbors[i], visit) == 0)
                    return false;
            }
            else if(visit[node->neighbors[i]->label] == 0)
                return false;
        }
        visit[node->label] = 1;
        return true;
    }
};
  • 方法二,宽度优先(拓扑结构)
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<GraphNode *> graph;
        vector<int> degree;
        //创建图
        for(int i=0; i<numCourses; i++) {
            graph.push_back(new GraphNode(i));
            degree.push_back(0);
        }

        //连接图
        for(int i=0; i<prerequisites.size(); i++) {
            GraphNode* begin = graph[prerequisites[i].second];
            GraphNode* end = graph[prerequisites[i].first];
            begin->neighbors.push_back(end);
            degree[prerequisites[i].first]++;
        }

        queue<GraphNode *> Q;
        for(int i=0; i<degree.size(); i++) {
            if(degree[i] == 0)
                Q.push(graph[i]);
        }

        while(!Q.empty()) {
            GraphNode* node = Q.front();
            Q.pop();
            for(int i=0; i<node->neighbors.size(); i++) {
                degree[node->neighbors[i]->label]--;
                if(degree[node->neighbors[i]->label] == 0)
                    Q.push(node->neighbors[i]);
            }
        }

        //回收内存
        for(int i=0; i<graph.size(); i++) {
            delete graph[i];
        }

        //回收内存
        for(int i=0; i<degree.size(); i++) {
            if (degree[i]){
                return false;
            }
        }
        return true;
    }
};
继续阅读
  • 我的微信小程序
  • 这是我的微信小程序扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
qlmx
  • 本文由 发表于 2020年2月15日00:18:01
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: