zoukankan      html  css  js  c++  java
  • [Leetcode Week3]Course Schedule

    Course Schedule题解

    原创文章,拒绝转载

    题目来源:https://leetcode.com/problems/course-schedule/description/


    Description

    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.

    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.

    Solution

    class Solution {
    private:
        bool **graph;
        int* color;
        int graphDim = 0;
    
    
    public:
        ~Solution() {
            if (graphDim == 0)
                return;
            delete[] color;
            for (int i = 0; i < graphDim; i++)
                delete[] graph[i];
            delete graph;
        }
    
        bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
            if (numCourses <= 0)
                return false;
            if (prerequisites.size() == 0)
                return true;
            int i, j;
    
            graphDim = numCourses;
            graph = new bool*[numCourses];
            color = new int[numCourses];
    
            for (i = 0; i < numCourses; i++)
                graph[i] = new bool[numCourses];
    
            for (i = 0; i < numCourses; i++) {
                color[i] = 0;
                for (j = 0; j < numCourses; j++) {
                    graph[i][j] = false;
                }
            }
    
            for (auto p: prerequisites) {
                graph[p.first][p.second] = true;
            }
    
            int sv;
            for (auto p: prerequisites) {
                sv = p.first;
                for (i = 0; i < numCourses; i++) {
                    if (graph[sv][i]) {
                        if (color[sv] == 2)
                            continue;
                        if (!dfs(sv))
                            return false;
                        else
                            color[i] = 2;
                    }
                }
            }
            return true;
        }
    
        bool dfs(int v) {
            color[v] = 1;
            int i;
            for (i = 0; i < graphDim; i++) {
                if (graph[v][i]) {
                    if (color[i] == 2) {
                        break;
                    } else if (color[i] == 1) {
                        return false;
                    } else {
                        if (!dfs(i)) {
                            return false;
                        }
                    }
                }
            }
            color[v] = 2;
            return true;
        }
    };
    
    

    解题描述

    这道题我使用的是DFS,过程中通过对以访问的顶点进行染色来判断是否有环。不过提交后出现了几次TLE,检查代码发现好几处可以充分利用染色数组来减少充分访问。改了好几次才AC。现实利用中DFS和BFS处理的数据量往往会很大,这几次TLE还是提醒我要注意优化算法时间复杂度。


    文章更新

    这道题本质上是检查图是否有环,而如果图是可以拓扑排序的,则一定是无环的。通过BFS检查图是否能够拓扑排序也是可以解决的,且相对来说实现效率较高,避免了DFS的递归开销。下面给出实现:

    class Solution
    {
    private:
        map<int, int> inDegree;
    public:
        bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
            int i, curVertex;
            for (i = 0; i < numCourses; i++)
                inDegree[i] = 0;
    
            for (auto p: prerequisites) 
                inDegree[p.second]++;
    
            queue<int> vq;
            for (i = 0; i < numCourses; i++) {
                if (inDegree[i] == 0) {
                    vq.push(i);
                }
            }
    
            if (vq.empty())
                return false;
    
            while (!vq.empty()) {
                curVertex = vq.front();
                vq.pop();
                inDegree.erase(curVertex);
                for (i = 0; i < prerequisites.size(); i++) {
                    if (curVertex == prerequisites[i].first) {
                        inDegree[prerequisites[i].second]--;
                        if (inDegree[prerequisites[i].second] == 0)
                            vq.push(prerequisites[i].second);
                    }
                }
            }
    
            return inDegree.empty();
        }    
    };
    
  • 相关阅读:
    《新人口论》摘录
    中国历史上农村剩余劳动力的安置政策
    sql 善后处理的一些代码
    淘宝骗家实录
    什么决定着我们的工作
    【原创】打造具有EnableWindow功能的SPYXX
    文件被锁住删除不了的一种解决方法
    去除页面中所有的标记
    用动网论坛做BUG管理,感觉还不错
    同事刚告诉我一不错的东东VNN
  • 原文地址:https://www.cnblogs.com/yanhewu/p/7588989.html
Copyright © 2011-2022 走看看