【LeetCode】拓扑排序
【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】拓扑排序的更多相关文章
- LeetCode编程训练 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- 拓扑排序(附LeetCode题目)
算法期中考到一题关于拓扑序的题目,觉得很值得一写. 1.什么是拓扑序? 对一个有向无环图进行拓扑排序,假如图中存在一条从顶点A到顶点B的路径,则拓扑序中顶点A出现在顶点B的前面.要注意的是,这是对有向 ...
- LeetCode 210. Course Schedule II(拓扑排序-求有向图中是否存在环)
和LeetCode 207. Course Schedule(拓扑排序-求有向图中是否存在环)类似. 注意到.在for (auto p: prerequistites)中特判了输入中可能出现的平行边或 ...
- [LeetCode] 207. 课程表(拓扑排序,BFS)
题目 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总量 ...
- 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 ...
- C#LeetCode刷题-拓扑排序
拓扑排序篇 # 题名 刷题 通过率 难度 207 课程表 40.0% 中等 210 课程表 II 39.8% 中等 329 矩阵中的最长递增路径 31.0% 困难
- UVa 872 - Ordering 输出全拓扑排序
本题要求输出所有拓扑排序的序列. 还好本题的数据量不是非常大.限制在26个大写英文字母,故此能够使用递归法输出. 这个递归输出所有解在Leetcode非常多这种题目的,不小心的话,还是非常难调试的. ...
- 算法与数据结构基础 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
随机推荐
- 【记录】iconfont 批量把图标加入购物车的方法
iconfont 是阿里旗下很好用的图标管理网站(https://www.iconfont.cn/),里面有百万个小图标,可以随意下载切换颜色,是很多前端人员的选择. 但是网站没有将图标批量加入购物 ...
- sqlacodegen:通过mysql语句生成sqlalchemy的model
引用网页描述:这个工具读取现有数据库的结构并生成相应的SQLAlchemy模型代码. 使用方法详细描述在如下连接中. 先简要介绍使用方法: 安装:pip install sqlacodegen sq ...
- go语言从例子开始之Example7.switch分支结构
switch ,方便的条件分支语句 package main import "fmt" import "time" func main() { 一个基本的 sw ...
- 关于ovf导入到Esxi上出显的“文件条目(行1)无效,sha256……”处理办法
通常删除同名文件*.mf文件即可导入!
- 练手项目之image caption问题记录
小白一个,刚刚费了老大的劲完成一个练手项目--image caption,虽然跑通了,但是评估结果却惨不忍睹.于是贴上大神的作品,留待日后慢慢消化.顺便记录下自己踩坑的一些问题. 先膜拜下大神的作品. ...
- chroot()使用
好多的程序,都有使用chroot来是程序chroot到一个目录下面,来保护文件系统,今天在看snort代码的时候,看到了实现,就贴出一个测试程序来,实际上是比较简单的. chroot()在lin ...
- sql中简单的触发器功能
触发器分为DML触发器和DDL触发器DML触发器包含After触发器,执行insert update delete语句后会触发after触发器,会事务回滚DML触发器还包含instead of触发器, ...
- SQL中循环的实现方式
一.第一种方法,游标 定义游标 DECLARE cur_ClubHeadCash CURSOR FAST_FORWARD READ_ONLY FOR,循环每行 FETCH NEXT FROM cur_ ...
- kvm无人值守安装centos6
nginx配置 server { listen default_server; server_name _; root /home/iso; # Load configuration files fo ...
- #include <utility>
#include <utility>这个头文件是什么用法 utility头文件定义了一个pair类型,是标准库的一部分,其原型为:template<class _Ty1, class ...