【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网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
随机推荐
- SSH工具
SSH是什么:SSH是一种网络协议,用于计算机之间的加密登录 应用:用来连接远程服务器 适用人员:需要操作服务器的程序员,linux管理员等 需要的基础知识: http://www.ee. ...
- css3 渐变色兼容移动端
.group_1 background #1a78f3 // 兼容不显示渐变色的浏览器 background: linear-gradient(180deg, #1a78f3 , #fff); bac ...
- java--字符串拼接比较
/** * 字符串拼接 */ public class StringAddDemo { public static void main(String[] args){ testStringAdd(); ...
- Delphi 字符串函数SysUtils单元 AnsiSameStr、AnsiSameText、AnsiCompareStr、AnsiCompareText、AnsiCompareFileName、AnsiUpperCase、AnsiLowerCase、AnsiUpperCaseFileName、AnsiLowerCaseFileName、AnsiPos、AnsiQuotedStr
USES 单元 SysUtils 非 StrUtils AnsiSameStr.AnsiSameText.AnsiCompareStr.AnsiCompareText.AnsiCompareFileN ...
- PHP filter_var_array() 函数
定义和用法 filter_var_array() 函数获取多个变量,并进行过滤. 该函数对过滤多个值很有用,无需重复调用 filter_var(). 如果成功,则以数组形式返回请求变量的值.如果失败, ...
- Network基础(五):配置静态路由、配置浮动路由、配置多路由的静态路由、配置默认路由
一.配置静态路由 目标: 配置路由接口IP地址并通过静态路由的配置实现全网的互通. 方案: 按如下网络拓扑配置接口IP地址并通过静态路由的配置实现全网的互通如下图所示: 步骤: 步骤一:配置静态路由 ...
- Vuetify按需加载配置
自己配置vuetify按需加载的步骤,在此记录: 执行npm install vuetify –save 或 yarn add vuetify添加vuetify添加依赖执行npm install -- ...
- #include <utility>
#include <utility>这个头文件是什么用法 utility头文件定义了一个pair类型,是标准库的一部分,其原型为:template<class _Ty1, class ...
- php中的list()
list()在php中上一个语言结构,并不是一个函数.类似array(),不过array()这个东西我们现在一般很少使用了,因为从php5.4版本开始,我们会直接使用[]来定义数组. 那么,list( ...
- Android 测试点归纳总结
前言 除了测试平台工具,业务测试的总结和思考同样重要,这里总结了一些Android测试知识点,可以辅助业务测试快速形成测试用例和检查点,当作抛砖引玉分享给大家.如有思考不全面的地方,欢迎大家指出来. ...