zoukankan      html  css  js  c++  java
  • leetcode 207. Course Schedule 、 210. Course Schedule II 、 310. Minimum Height Trees

    207. Course Schedule

    https://blog.csdn.net/wongleetion/article/details/79433101

    问题的实质就是判断一个有向图是否有环,利用入度去解决这个问题

    使用bfs解决问题。

    初始化时,利用二维vector存储节点间的关系,并存储每个节点的入度,同时将入度为0的节点放入队列,这是图的起始点。

    每次将队列中的节点弹出后,然后将对应的课程的入度减少,如果有此时产生入度为0的节点,再加入队列中,直到队列为空。

    最终判断整个入度的存储是否还有节点入度不为0。

    class Solution {
    public:
        bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
            vector<vector<int>> graph(numCourses,vector<int>(0));
            vector<int> inDegree(numCourses,0);
            for(auto i : prerequisites){
                graph[i.second].push_back(i.first);
                inDegree[i.first]++;
            }
            
            queue<int> q;
            for(int i = 0;i < numCourses;i++){
                if(inDegree[i] == 0)
                    q.push(i);
            }
            
            while(!q.empty()){
                int num = q.front();
                q.pop();
                for(auto i : graph[num]){
                    inDegree[i]--;
                    if(inDegree[i] == 0)
                        q.push(i);
                }
            }
            
            for(int i = 0;i < numCourses;i++){
                if(inDegree[i] != 0)
                    return false;
            }
            return true;
        }
    };

    210. Course Schedule II

    这个题是要你把学习课程的路径求出来,如果有环,就返回空数组。

    这个题基本上与Course Schedule代码差不多,只需要每次在queue弹出的时候存入结果就好,还需要判断是否有环。

    class Solution {
    public:
        vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
            vector<vector<int>> graph(numCourses);
            vector<int> indegree(numCourses);
            vector<int> result;
            for(int i = 0;i < prerequisites.size();i++){
                graph[prerequisites[i][1]].push_back(prerequisites[i][0]);
                indegree[prerequisites[i][0]]++;
            }
            queue<int> q;
            for(int i = 0;i < numCourses;i++){
                if(indegree[i] == 0)
                    q.push(i);
            }
            while(!q.empty()){
                int course = q.front();
                q.pop();
                result.push_back(course);
                for(int i = 0;i < graph[course].size();i++){
                    indegree[graph[course][i]]--;
                    if(indegree[graph[course][i]] == 0)
                        q.push(graph[course][i]);
                }
            }
            vector<int> res;
            for(int i = 0;i < numCourses;i++){
                if(indegree[i] != 0)
                    return res;
            }
            return result;
        }
    };

    310. Minimum Height Trees

    https://www.cnblogs.com/grandyang/p/5000291.html

    给定一个拥有树性质的无向图,图的每一个节点都可以视为一棵树的根节点。在所有可能的树中,找出高度最小的树,并返回他们的树根。

    如果剩余的节点数超过两个,就可以继续去除叶节点,比如剩余了3个节点,那么其实可以把外面的两个节点去掉,就只剩一个节点了,而且以这个节点做根,得到的树的高度最小;而如果剩余了2个节点,那么不论让谁当根,得到的高度都是一样的;如果剩余一个,自然不必多说就是根节点了。

    我们开始将所有只有一个连接边的节点(叶节点)都存入到一个队列queue中,然后我们遍历每一个叶节点,通过图来找到和其相连的节点,并且在其相连节点的集合中将该叶节点删去,如果删完后此节点也也变成一个叶节点了,加入队列中,再下一轮删除。那么我们删到什么时候呢,当节点数小于等于2时候停止,此时剩下的一个或两个节点就是我们要求的最小高度树的根节点

    class Solution {
    public:
        vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
            if(n == 1)
                return {0};
            vector<int> res;
            vector<unordered_set<int>> adj(n);
            queue<int> q;
            for(int i = 0;i < edges.size();i++){
                adj[edges[i][0]].insert(edges[i][1]);
                adj[edges[i][1]].insert(edges[i][0]);
            }
            for(int i = 0;i < n;i++){
                if(adj[i].size() == 1)
                    q.push(i);
            }
            while(n > 2){
                int size = q.size();
                n -= size;
                for(int i = 0;i < size;i++){
                    int tmp = q.front();
                    q.pop();
                    for(auto j : adj[tmp]){
                        adj[j].erase(tmp);
                        if(adj[j].size() == 1)
                            q.push(j);
                    }
                }
            }
            while(!q.empty()){
                int tmp = q.front();
                q.pop();
                res.push_back(tmp);
            }
            return res;
        }
    };
  • 相关阅读:
    Android Service组件在新进程绑定(bindService)过程
    第二章:创建框架和窗体
    ZOJ 2859 二维RMQ(模板)
    POJ 2828 Buy Tickets
    管理案例:怎样提高项目周例会的效率和效果?
    hdu4416 Good Article Good sentence (后缀数组)
    购买DigtalOcean VPS 安装Wordpress 攻略
    Asteroids!-裸的BFS
    hdu3015 Disharmony Trees
    iOS开发-自己定义后台显示图片(iOS7-Background Fetch的应用)
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/10521750.html
Copyright © 2011-2022 走看看