【207】 Course Schedule

排课问题,n门课排课,有的课程必须在另外一些课程之前上,问能不能排出来顺序。

题解:裸的拓扑排序。参考代码见算法竞赛入门指南这本书。

 class Solution {
public:
bool dfs(const vector<vector<int>>& g, vector<int>& c, int u) {
c[u] = -;
for (int v = ; v < n; ++v) {
if (g[u][v]) {
if (c[v] < ) { return false; }
else if (!c[v] && !dfs(g, c, v)) {
return false;
}
}
}
c[u] = ;
topo[--t] = u;
return true;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> graph(numCourses, vector<int>(numCourses, ));
n = numCourses;
topo.resize(n);
t = n;
for (auto ele : prerequisites) {
int u = ele.first, v = ele.second;
graph[v][u] = ;
}
vector<int> c(n, );
for (int i = ; i < n; ++i) {
if (!c[i]) {
if (!dfs(graph, c, i)) {
return false;
}
}
}
/*
for (int i = 0; i < n; ++i) {
cout << topo[i] << " " ;
}
cout << endl;
*/
return true;
}
vector<int> topo;
int n, t;
};

【210】 Course Schedule II

同上一个排课问题,这次的问题是能不能给出一个可行的顺序。

题解:还是裸的拓扑排序。

 class Solution {
public:
bool dfs(vector<int>& c, vector<int>& topo, int u) {
c[u] = -;
for (int v = ; v < n; ++v) {
if (g[u][v]) {
if (c[v] < ) {return false;}
else if (!c[v] && !dfs(c, topo, v)) {return false; }
}
}
c[u] = ;
topo[--t] = u;
return true;
}
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
n = numCourses, t = n;
vector<int> topo(n, );
vector<int> c(n, );
vector<vector<int>> graph(n, vector<int>(n, ));
for (auto ele : prerequisites) {
int u = ele.first, v = ele.second;
graph[v][u] = ;
}
g = graph; for (int u = ; u < n; ++u) {
if (!c[u]) {
if (!dfs(c, topo, u)) {
vector<int> temp;
return temp;
}
}
}
return topo;
}
int n, t;
vector<vector<int>> g;
};

【269】 Alien Dictionary

给了一门新的语言,给了一个单词字典,所有的单词按照字典序排序。要求返回现有字母的顺序,没有顺序的话,返回空数组。

题解:逐个比较两个相邻的单词,如果他们第i个位置不同,说明前一个单词的第i个字母u,要小于后一个单词的第i个字母v,然后建图,建完图直接裸的拓扑排序。

 class Solution {
public:
bool dfs(int u) {
c[u] = -;
for (int v = ; v < tot; ++v) {
if (g[u][v]) {
if (c[v] < ) {return false;}
else if (!c[v] && !dfs(v)) {return false;}
}
}
c[u] = ;
topo[--cur] = u;
return true;
} string alienOrder(vector<string>& words) {
vector<pair<int, int>> order;
const int n = words.size();
int t = ;
for (int i = ; i < n; ++i) {
string word = words[i];
for (auto ele : word) {
if (mpCh2Num.find(ele) == mpCh2Num.end()) {
mpCh2Num[ele] = t;
mpNum2Ch[t] = ele;
++t;
}
}
}
c.resize(t), topo.resize(t);
tot = t; cur = t; for (int i = ; i < n - ; ++i) {
string word1 = words[i], word2 = words[i+];
for (int idx = ; idx < min(word1.size(), word2.size()); ++idx) {
if (word1[idx] != word2[idx]) {
pair<int, int> p = make_pair(mpCh2Num[word1[idx]], mpCh2Num[word2[idx]]);
order.push_back(p);
break;
}
}
} vector<vector<int>> graph(t, vector<int>(t, ));
for (auto ele : order) {
int u = ele.first, v = ele.second;
graph[u][v] = ;
}
g = graph; for (int u = ; u < t; ++u) {
if (!c[u]) {
if (!dfs(u)) {
string temp;
return temp;
}
}
}
string ans;
for (auto ele : topo) {
ans += mpNum2Ch[ele];
}
return ans;
}
vector<vector<int>> g;
vector<int> c, topo;
map<int, char> mpNum2Ch;
map<char, int> mpCh2Num;
int tot;
int cur;
};

【329】 Longest Increasing Path in a Matrix

给了一个矩阵matrix, 一个点他可以朝着上下左右四个方向走,问这个矩阵能走出来的最长递增的路径的长度是多少。

题解:裸的dfs会超时,所以加上了一个记忆化数组过了。题目的解法三有拓扑排序的相关解法,下次要搞懂那个解法。

 class Solution {
public:
void print(vector<vector<int>>& mat) {
const int n = mat.size(), m = mat[].size();
for (int i = ; i < n; ++i) {
for (int j = ; j < m; ++j) {
cout << mat[i][j] << " ";
}
cout << endl;
}
}
int dirx[] = {-, , , };
int diry[] = {, -, , };
int dfs(const vector<vector<int>>& mat, int x, int y, vector<vector<int>>& vis) {
vis[x][y] = ;
for (int i = ; i < ; ++i) {
int newx = x + dirx[i], newy = y + diry[i];
if (newx >= && newx < n && newy >= && newy < m && !vis[newx][newy]&& mat[newx][newy] > mat[x][y]) {
if (memo[newx][newy] != ) {
memo[x][y] = max(memo[x][y], memo[newx][newy] + );
} else {
memo[x][y] = max(memo[x][y], dfs(mat, newx, newy, vis) + );
}
}
}
vis[x][y] = ;
return memo[x][y];
}
int longestIncreasingPath(vector<vector<int>>& matrix) {
n = matrix.size();
if (n == ) { return ; }
m = matrix[].size();
if (m == ) { return ; } int ans = ;
memo = matrix;
for (int i = ; i < n; ++i) {
for (int j = ; j < m; ++j) {
memo[i][j] = ;
}
} for (int i = ; i < n; ++i) {
for (int j = ; j < m; ++j) {
vector<vector<int>> vis(n, vector<int>(m, ));
memo[i][j] = dfs(matrix, i, j, vis);
ans = max(ans, memo[i][j]);
}
}
return ans +;
}
int n, m;
vector<vector<int>> memo;
};

【444】 Sequence Reconstruction

【LeetCode】拓扑排序的更多相关文章

  1. LeetCode编程训练 - 拓扑排序(Topological Sort)

    拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...

  2. 拓扑排序(附LeetCode题目)

    算法期中考到一题关于拓扑序的题目,觉得很值得一写. 1.什么是拓扑序? 对一个有向无环图进行拓扑排序,假如图中存在一条从顶点A到顶点B的路径,则拓扑序中顶点A出现在顶点B的前面.要注意的是,这是对有向 ...

  3. LeetCode 210. Course Schedule II(拓扑排序-求有向图中是否存在环)

    和LeetCode 207. Course Schedule(拓扑排序-求有向图中是否存在环)类似. 注意到.在for (auto p: prerequistites)中特判了输入中可能出现的平行边或 ...

  4. [LeetCode] 207. 课程表(拓扑排序,BFS)

    题目 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总量 ...

  5. LeetCode 207. Course Schedule(拓扑排序)

    题目 There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have p ...

  6. C#LeetCode刷题-拓扑排序

    拓扑排序篇 # 题名 刷题 通过率 难度 207 课程表   40.0% 中等 210 课程表 II   39.8% 中等 329 矩阵中的最长递增路径   31.0% 困难 ​​​​​​​

  7. UVa 872 - Ordering 输出全拓扑排序

    本题要求输出所有拓扑排序的序列. 还好本题的数据量不是非常大.限制在26个大写英文字母,故此能够使用递归法输出. 这个递归输出所有解在Leetcode非常多这种题目的,不小心的话,还是非常难调试的. ...

  8. 算法与数据结构基础 - 拓扑排序(Topological Sort)

    拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...

  9. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

随机推荐

  1. phpredis中incr以及decr等自增命令出现的问题

    在做项目中使用redis的incr以及hincrby自增时,出现自增失败,set之后的数据,无法自增,当redis中不存在该key时,直接用incr是成功的.查找了原因,是因为phpredis初始化的 ...

  2. 在 Visual Studio 中使用 Q# 进行量子编程

    1 量子计算机与量子编程 1.1 量子计算机 Quantum computing is computing using quantum-mechanical phenomena, such as su ...

  3. 重学JavaScript - 映射与集合

    作者:狐狸家的鱼 GitHub:surRimn 整理自MDN文档 带键的集合 映射 Map对象 一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for...of 循环在每次迭代后会返 ...

  4. centos 安装mysql冲突解决方法

    [root@centos-50 servers]# rpm -ivh mysql-server-5.5.33-1.linux2.6.x86_64.rpm Preparing... ########## ...

  5. PHP disk_total_space() 函数

    定义和用法 disk_total_space() 函数返回指定目录的磁盘总容量,以字节为单位. 语法 disk_total_space(directory) 参数 描述 directory 必需.规定 ...

  6. OC学习篇之---类的三大特性(封装,继承,多态)

    之前的一片文章介绍了OC中类的初始化方法和点语法的使用:http://blog.csdn.net/jiangwei0910410003/article/details/41683873,今天来继续学习 ...

  7. JVM 和JMM的区别

    首先从定义上看 JVM (Java Virtual Machine)Java虚拟机模型 主要描述的是Java虚拟机内部的结构以及各个结构之间的关系. JMM(Java Memory Model) Ja ...

  8. Jplayer用法

    引用js:jquery.jplayer.min.js; body里面必须有这个: <div id="jplayer"></div> jplayer停止方法 ...

  9. oracle服务端导出/导入方式expdp/impdp

    1. expdp导出步骤 1.1 用sys管理员登录sqlplus [root@hxjk_test_mysql_redis_file oracle]# sqlplus SQL*Plus: Releas ...

  10. mysql分表分库 ,读写分离

    1.分表 当项目上线后,数据将会几何级的增长,当数据很多的时候,读取性能将会下降,更新表数据的时候也需要更新索引,所以我们需要分表,当数据量再大的时候就需要分库了. a.水平拆分:数据分成多个表 b. ...