207&210. Course Schedule

来源:互联网 发布:手机电池修复软件下载 编辑:程序博客网 时间:2024/05/30 12:03

一、题目简述

  • 共有n门课需要选择,使用0n1进行标记。其中部分课程存在依赖关系,例如课程0必须在修学过课程1的基础上可以上,使用对[0,1]表示。
  • 给定课程数量和依赖关系对,返回完成所有课程的顺序。 存在多种可能的正确顺序,只需返回其中一个即可,如果无法完成所有课程,则返回一个空序列。

例如:输入 2,[[1,0]],输出[0,1]
输入 4,[[1,0],[2,0],[3,1],[3,2]],输出[0,1,2,3],还有一种正确的选修顺序为[0,2,1,3].

二、编程思路

  • 本题将课程作为节点,课程之间的前置关系作为有向边,对给出的图进行拓扑排序即可。
  • 在拓扑排序过程中需要记录每个节点是否被访问过,及入度信息。分别使用is_vstin_dg两个数组记录。
  • 首先计算每个节点的入度,之后每次选出入度为零未被访问过的节点p,找到由p出发的有向边,将其终点的入度减1,将节点p放入存放路径的vector vst_seq中之后重复进行循环。直到所有的节点都被访问完毕,返回vst_seq;若未访问过的节点的入度都不为零,说明中存在,返回空vector

三、程序设计

class Solution {public:    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {        int in_dg[numCourses]={0};//in degree        bool is_vst[numCourses]={false};        vector<int> vst_seq;        for(int i=0;i<prerequisites.size();i++){            in_dg[prerequisites[i].first]++;        }        while(1){            // for(int i=0;i<numCourses;i++){            //  cout<<in_dg[i]<<" ";            // }            // cout<<endl;            // cout<<"in while"<<endl;            bool is_all_vst=true;            for(int k=0;k<numCourses;k++){                if(!is_vst[k]){                    is_all_vst=false;                    break;                }            }            if(is_all_vst){                return vst_seq;                // return true;            }            int i;            for(i=0;i<numCourses;i++){                if((!in_dg[i]) && (!is_vst[i])){                    vst_seq.push_back(i);                    is_vst[i]=true;                    break;                }            }            // cout<<i<<endl;            if(i==numCourses){                vector<int> v;                return v;                // return false;            }            for(int j=0;j<prerequisites.size();j++){                if(prerequisites[j].second==i){                    in_dg[prerequisites[j].first]--;                }            }        }    }};

四、实验心得

本题中使用vector存放prerequisites信息,由于vector无法删除某个位置的元素,故每次寻找某个节点为起点,与其相邻的节点时,需要重新搜索整个prerequisites,较为浪费时间。可以使用list存放边,将搜索过的边删除,从而减少搜索时间。

0 0
原创粉丝点击