题目:

基于宽度优先搜索的拓扑排序

思路:

这个问题相当查找有向图中是否存在环。逐个删除入度为0的节点,当删除的节点数量等于输入的所有节点数量时,判定不存在环。

拓扑排序最好使用邻接链表存储邻接关系,而非使用邻接矩阵。因为邻接链表在能够非常直接查找到邻接节点,查找操作耗时O(m+n),而邻接矩阵需要进行遍历才能查找到邻接节点,查找操作耗时O(n^2)。其中n为节点数量,m为边的数量。

本算法的时间复杂度和空间复杂度都比较大,原因在于创建了邻接矩阵存储邻接关系。导致在查找邻接关系的时候,需要进行遍历操作,时间复杂度为O(n^2)。

执行用时 :60 ms, 在所有 cpp 提交中击败了32.55%的用户
内存消耗 :81.6 MB, 在所有 cpp 提交中击败了5.21%的用户
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if(prerequisites.size() == )
return true; vector< vector<int> > mat( numCourses, vector<int>(numCourses,) );
vector<int> numR(numCourses, );
vector<int> stack(numCourses, );
vector<int> tIn;
int top = , count = ; for(int i = ; i < prerequisites.size(); ++i) {
tIn = prerequisites[i];
mat[tIn[]][tIn[]] = ;
numR[tIn[]] += ;
} for(int j = ; j < numCourses; ++j) {
if(numR[j] == ) {
stack[top++] = j;
}
} while(top > ) {
int gettop = stack[--top];
count += ; for(int k = ; k < numCourses; ++k) {
if(mat[gettop][k] == ) {
numR[k] -= ; if(numR[k] == )
stack[top++] = k;
}
}
} if(count == numCourses )
return true;
else
return false;
}
};

对上述算法进行改进。将邻接矩阵换成邻接链表。时间复杂度为O(m+n),耗时大大缩小。

执行用时 :24 ms, 在所有 cpp 提交中击败了93.35%的用户
内存消耗 :12.9 MB, 在所有 cpp 提交中击败了19.07%的用户
注意,这里巧妙使用vector<vector<int>>数据类型创建了“邻接链表”。
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if(prerequisites.size() == )
return true; vector< vector<int> > mat(numCourses);
vector<int> numR(numCourses, );
vector<int> stack(numCourses, );
vector<int> tIn;
int top = , count = ; for(int i = ; i < prerequisites.size(); ++i) {
tIn = prerequisites[i];
mat[tIn[]].push_back(tIn[]);
numR[tIn[]] += ;
} for(int j = ; j < numCourses; ++j) {
if(numR[j] == ) {
stack[top++] = j;
}
} while(top > ) {
int gettop = stack[--top];
count += ; for(int k = ; k < mat[gettop].size(); ++k) {
numR[mat[gettop][k]] -= ; if(numR[mat[gettop][k]] == )
stack[top++] = mat[gettop][k];
}
} if(count == numCourses )
return true;
else
return false;
}
};

基于深度优先搜索的拓扑排序

时间复杂度:排序过程为O(n+m),其中n为节点数量,m为边数量。构建邻接链表为O(m)。

空间复杂度:邻接链表占据空间为O(m);标识数组占据空间为O(n);递归过程的栈内存最大为O(n),此时拓扑序列为一条链。

class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if(prerequisites.size() == )
return true; vector< vector<int> > mat(numCourses);
vector<int> flag(numCourses, );
vector<int> tIn; for(int i = ; i < prerequisites.size(); ++i) {
tIn = prerequisites[i];
mat[tIn[]].push_back(tIn[]);
} bool ans = true;
for(int i = ; i < numCourses; ++i) {
ans = ans&&dfsF(i, flag, mat); // 每一条路线不允许存在回路,所以是“&&”逻辑
}
return ans;
} bool dfsF(int i, vector<int>& flag, const vector<vector<int> >& matC){
if(flag[i] == )
return true; if(flag[i] == -)
return false; flag[i] = -;
for(int j = ; j < matC[i].size(); ++j) {
if(dfsF(matC[i][j], flag, matC))
continue;
else
return false;
} flag[i] = ;
return true;
}
};

关于namespace的使用的更多相关文章

  1. 理解Docker(3):Docker 使用 Linux namespace 隔离容器的运行环境

    本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  2. C++ namespace

    namespace, 命名空间, 用于解决命名冲突的问题. Python中的package/module, Javascript中的object, Java中的package都具有这样的功能. 如何使 ...

  3. C++ 之namespace常见用法

    一.背景 需要使用Visual studio的C++,此篇对namespace的常用用法做个记录. 二.正文 namespace通常用来给类或者函数做个区间定义,以使编译器能准确定位到适合的类或者函数 ...

  4. using namespace std 和 using std::cin

    相较using std::cin使用using namespace std不会使得程序的效率变低,或者稳定性降低,只是这样作会将很多的名字引入程序,使得程序员使用的名字集合变小,容易引起命名冲突. 在 ...

  5. Why Namespace? - 每天5分钟玩转 OpenStack(102)

    上一节我们讨论了 Neutron 将虚拟 router 放置到 namespace 中实现了不同 subnet 之间的路由.今天探讨为什么要用 namespace 封装 router? 回顾一下前面的 ...

  6. struts2中错误There is no Action mapped for namespace [/] and action name [] associated with context path

    1 There is no Action mapped for namespace [/] and action name [] associated with context path [/Stru ...

  7. PHP 命名空间(namespace)

    PHP 命名空间(namespace) PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物. 不过在PHP当中还是有着相当重要的意义 ...

  8. AMD and CMD are dead之Why Namespace?

    缘由 当我看到_Franky兄的微博的时候: 我觉得我有必要出来详细说说KMDjs到底有什么本质上的优势了,连教主_Franky.貘吃馍香都不能理解他的好处,那么可想而知,在前端圈.或是全端圈.或是I ...

  9. 使用mvc时,在视图view中使用强类型视图,在web.config文件中添加命名空间namespace的引用不起作用,解决方法

    这是view中的model代码: @model t_user_info 这是web.config配置文件只的代码: <namespaces> <add namespace=" ...

  10. C、C++: 引用、指针、实例、内存模型、namespace

    // HelloWorld.cpp : Defines the entry point for the console application. // #include "stdafx.h& ...

随机推荐

  1. Oracle对象(视图、序列、索引)

    数据库对象:表.视图.序列.索引.同义词创建视图:create view 名 as 子查询描述结构:describe 对象名修改视图:create or replace view 名 as 子查询 视 ...

  2. phpStrom--我常用的快捷键

    ALT+ ←/→  切换代码视图,标签切换 ALT+ ↑/↓  在方法间快速移动定位 ctrl+shift+r  查找 替换 alt+ctrl+l 格式化代码 CTRL+N   查找类 CTRL+W  ...

  3. 爬格子问题(经典强化学习问题) Sarsa 与 Q-Learning 的区别

    SARSA v.s. Q-learning 爬格子问题,是典型的经典强化学习问题. 动作是上下左右的走,每走一步就会有一个-1的奖赏.从初始状态走到最终的状态,要走最短的路才能使奖赏最大.图中有一个悬 ...

  4. FileNotFoundError: [Errno 2] No such file or directory的解决方法

    1.获取当前文件所在路径 basedir = os.path.dirname(__file__) print("basedir:" + basedir) 2.将路径进行拼接 upl ...

  5. IDEA 导出项目war包

    部署 Maven 项目,使用 “mvn package” 命令出现错误,不能正确打包时的解决方法 一.最简单.最快的方式: 思路,本地能运行,直接把本地编译后能正确运行的项目文件打包,传到服务器部署即 ...

  6. MySQL--使用innodb_force_recovery修复数据库异常

    当MySQL服务异常重启失败后,可以通过配置参数innodb_force_recovery来对MySQL服务进行修复启动. 参数innodb_force_recovery选项: 1 (SRV_FORC ...

  7. day 46 html 学习 列 表格,

    列表 1.无序列表 <ul type="disc"> <li>第一项</li> <li>第二项</li> </ul ...

  8. debezium sql server 集成

    debezium 是一个方便的cdc connector 可以帮助我们解决好多数据实时变更处理.数据分析.微服务的数据通信 从上次跑简单demo到现在,这个工具是有好多的变更,添加了好多方便的功能,支 ...

  9. 记录:禁用你的元素 bootstrap

    记录:禁用你的元素 bootstrap <script> $(document).ready(function() { $("#target1").css(" ...

  10. 艰苦的编译boost python (失败)

    1.下载 boost_1_67_0 2.在目录下执行 bootstrap 3.将python36添加到path环境变量 4.执行 b2 --with-python,将会声场如下dll 2018/04/ ...