【207】 Course Schedule

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

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

 1 class Solution {
 2 public:
 3     bool dfs(const vector<vector<int>>& g, vector<int>& c, int u) {
 4         c[u] = -1;
 5         for (int v = 0; v < n; ++v) {
 6             if (g[u][v]) {
 7                 if (c[v] < 0) { return false; }
 8                 else if (!c[v] && !dfs(g, c, v)) {
 9                     return false;
10                 }
11             }
12         }
13         c[u] = 1;
14         topo[--t] = u;
15         return true;
16     }
17     bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
18         vector<vector<int>> graph(numCourses, vector<int>(numCourses, 0));
19         n = numCourses;
20         topo.resize(n);
21         t = n;
22         for (auto ele : prerequisites) {
23             int u = ele.first, v = ele.second;
24             graph[v][u] = 1;
25         }
26         vector<int> c(n, 0);
27         for (int i = 0; i < n; ++i) {
28             if (!c[i]) {
29                 if (!dfs(graph, c, i)) {
30                     return false;
31                 }
32             }
33         }
34         /*
35         for (int i = 0; i < n; ++i) {
36             cout << topo[i] << " " ;
37         }
38         cout << endl;
39         */
40         return true;
41     }
42     vector<int> topo;
43     int n, t;
44 };

View Code

【210】 Course Schedule II

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

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

 1 class Solution {
 2 public:
 3     bool dfs(vector<int>& c, vector<int>& topo, int u) {
 4         c[u] = -1;
 5         for (int v = 0; v < n; ++v) {
 6             if (g[u][v]) {
 7                 if (c[v] < 0) {return false;}
 8                 else if (!c[v] && !dfs(c, topo, v)) {return false; }
 9             }
10         }
11         c[u] = 1;
12         topo[--t] = u;
13         return true;
14     }
15     vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
16         n = numCourses, t = n;
17         vector<int> topo(n, 0);
18         vector<int> c(n, 0);
19         vector<vector<int>> graph(n, vector<int>(n, 0));
20         for (auto ele : prerequisites) {
21             int u = ele.first, v = ele.second;
22             graph[v][u] = 1;
23         }
24         g = graph;
25
26         for (int u = 0; u < n; ++u) {
27             if (!c[u]) {
28                 if (!dfs(c, topo, u)) {
29                     vector<int> temp;
30                     return temp;
31                 }
32             }
33         }
34         return topo;
35     }
36     int n, t;
37     vector<vector<int>> g;
38 };

View Code

【269】 Alien Dictionary

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

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

 1 class Solution {
 2 public:
 3     bool dfs(int u) {
 4         c[u] = -1;
 5         for (int v = 0; v < tot; ++v) {
 6             if (g[u][v]) {
 7                 if (c[v] < 0) {return false;}
 8                 else if (!c[v] && !dfs(v)) {return false;}
 9             }
10         }
11         c[u] = 1;
12         topo[--cur] = u;
13         return true;
14     }
15
16     string alienOrder(vector<string>& words) {
17         vector<pair<int, int>> order;
18         const int n = words.size();
19         int t = 0;
20         for (int i = 0; i < n; ++i) {
21             string word = words[i];
22             for (auto ele : word) {
23                 if (mpCh2Num.find(ele) == mpCh2Num.end()) {
24                     mpCh2Num[ele] = t;
25                     mpNum2Ch[t] = ele;
26                     ++t;
27                 }
28             }
29         }
30         c.resize(t), topo.resize(t);
31         tot = t; cur = t;
32
33         for (int i = 0; i < n - 1; ++i) {
34             string word1 = words[i], word2 = words[i+1];
35             for (int idx = 0; idx < min(word1.size(), word2.size()); ++idx) {
36                 if (word1[idx] != word2[idx]) {
37                     pair<int, int> p = make_pair(mpCh2Num[word1[idx]], mpCh2Num[word2[idx]]);
38                     order.push_back(p);
39                     break;
40                 }
41             }
42         }
43
44         vector<vector<int>> graph(t, vector<int>(t, 0));
45         for (auto ele : order) {
46             int u = ele.first, v = ele.second;
47             graph[u][v] = 1;
48         }
49         g = graph;
50
51         for (int u = 0; u < t; ++u) {
52             if (!c[u]) {
53                 if (!dfs(u)) {
54                     string temp;
55                     return temp;
56                 }
57             }
58         }
59         string ans;
60         for (auto ele : topo) {
61             ans += mpNum2Ch[ele];
62         }
63         return ans;
64     }
65     vector<vector<int>> g;
66     vector<int> c, topo;
67     map<int, char> mpNum2Ch;
68     map<char, int> mpCh2Num;
69     int tot;
70     int cur;
71 };

View Code

【329】 Longest Increasing Path in a Matrix

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

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

 1 class Solution {
 2 public:
 3     void print(vector<vector<int>>& mat) {
 4         const int n = mat.size(), m = mat[0].size();
 5         for (int i = 0; i < n; ++i) {
 6             for (int j = 0; j < m; ++j) {
 7                 cout << mat[i][j] << " ";
 8             }
 9             cout << endl;
10         }
11     }
12     int dirx[4] = {-1, 0, 1, 0};
13     int diry[4] = {0, -1, 0, 1};
14     int dfs(const vector<vector<int>>& mat, int x, int y, vector<vector<int>>& vis) {
15         vis[x][y] = 1;
16         for (int i = 0; i < 4; ++i) {
17             int newx = x + dirx[i], newy = y + diry[i];
18             if (newx >= 0 && newx < n && newy >= 0 && newy < m && !vis[newx][newy]&& mat[newx][newy] > mat[x][y]) {
19                 if (memo[newx][newy] != 0) {
20                     memo[x][y] = max(memo[x][y], memo[newx][newy] + 1);
21                 } else {
22                     memo[x][y] = max(memo[x][y], dfs(mat, newx, newy, vis) + 1);
23                 }
24             }
25         }
26         vis[x][y] = 0;
27         return memo[x][y];
28     }
29     int longestIncreasingPath(vector<vector<int>>& matrix) {
30         n = matrix.size();
31         if (n == 0) { return 0; }
32         m = matrix[0].size();
33         if (m == 0) { return 0; }
34
35         int ans = 0;
36         memo = matrix;
37         for (int i = 0; i < n; ++i) {
38             for (int j = 0; j < m; ++j) {
39                 memo[i][j] = 0;
40             }
41         }
42
43         for (int i = 0; i < n; ++i) {
44             for (int j = 0; j < m; ++j) {
45                 vector<vector<int>> vis(n, vector<int>(m, 0));
46                 memo[i][j] = dfs(matrix, i, j, vis);
47                 ans = max(ans, memo[i][j]);
48             }
49         }
50         return ans  +1;
51     }
52     int n, m;
53     vector<vector<int>> memo;
54 };

View Code

【444】 Sequence Reconstruction

转载于:https://www.cnblogs.com/zhangwanying/p/9655103.html

【LeetCode】拓扑排序相关推荐

  1. LeetCode 207. Course Schedule--有向图找环--面试算法题--DFS递归,拓扑排序迭代--Python

    题目地址:Course Schedule - LeetCode There are a total of n courses you have to take, labeled from 0 to n ...

  2. LeetCode Course Schedule II(拓扑排序)

    问题:给出个课程个数,及前提条件对[v,u],即修课程v之前需要修课程u,如果可以输出修的课程顺序 思路: 对于有向图的拓扑排序 一种方式是使用dfs,访问结点的状态分为三种,white,gray,b ...

  3. leetcode 310. Minimum Height Trees | 310. 最小高度树(图的邻接矩阵DFS / 拓扑排序)

    题目 https://leetcode.com/problems/minimum-height-trees/ 题解 方法1:图的邻接矩阵 DFS(超时) 我一想,这不就是个图嘛,于是随手敲出一个 DF ...

  4. LeetCode 2192. 有向无环图中一个节点的所有祖先(拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个正整数 n ,它表示一个 有向无环图 中节点的数目,节点编号为 0 到 n - 1 (包括两者). 给你一个二维整数数组 edges ,其中 ed ...

  5. LeetCode 2050. 并行课程 III(拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数 n ,表示有 n 节课,课程编号从 1 到 n . 同时给你一个二维整数数组 relations ,其中 relations[j] = [p ...

  6. LeetCode 1786. 从第一个节点出发到最后一个节点的受限路径数(迪杰斯特拉 + 拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 现有一个加权无向连通图. 给你一个正整数 n ,表示图中有 n 个节点,并按从 1 到 n 给节点编号:另给你一个数组 edges ,其中每个 edges ...

  7. LeetCode 1743. 从相邻元素对还原数组(拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 存在一个由 n 个不同元素组成的整数数组 nums ,但你已经记不清具体内容. 好在你还记得 nums 中的每一对相邻元素. 给你一个二维整数数组 adj ...

  8. LeetCode 1203. 项目管理(两次拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 公司共有 n 个项目和 m 个小组,每个项目要不无人接手,要不就由 m 个小组之一负责. group[i] 表示第 i 个项目所属的小组,如果这个项目目前 ...

  9. LeetCode 802. 找到最终的安全状态(逆向图+拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走. 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止. 现在, 如果我们最后 ...

  10. LeetCode 851. 喧闹和富有(拓扑排序)

    文章目录 1. 题目 2. 解题 1. 题目 在一组 N 个人(编号为 0, 1, 2, ..., N-1)中,每个人都有不同数目的钱,以及不同程度的安静(quietness). 为了方便起见,我们将 ...

最新文章

  1. python 管道 异步读取 select_Python通过select实现异步IO的方法
  2. long转string类型_从php内核角度分析php弱类型
  3. 恢复错误:\anaconda3\lib\site-packages\zmq\backend\cffi\__pycache__\_cffi_ext.c(266)
  4. 什么是光纤的波长?看看有哪些是你不知道的!
  5. 定义派生类和继承类(从汇编分析)
  6. maven 项目报错Context initialization failed
  7. 载荷谱matlab,收获机车架载荷测试及载荷谱编制方法研究
  8. 用async 解放你的大脑
  9. Probe:Android线上OOM问题定位组件
  10. IIS 7.0 部署MVC
  11. devops对大会的看法_哪条建议对您在DevOps的职业生涯影响最大?
  12. php ajax.open的 url路径,php – 检测Ajax调用URL
  13. node开发命令行脚本
  14. centos6.5 install cobbler
  15. 教你如何配置IIS Rewrite模块写规则
  16. 12.15daily_scrum
  17. 薄荷Android团队招聘啦
  18. 阅读STC(宏晶)公司的芯片手册知识
  19. 淘宝/天猫买家信息 API
  20. Pandas Query 方法深度总结

热门文章

  1. Python -- post方式上传文件
  2. FineReport报表和J2EE应用的集成
  3. C++中const、volatile、mutable的用法
  4. [react] 什么是浅层渲染?
  5. [html] 页面上的登录表单记住了密码(显示星号),但我又忘了密码,如何找回这个密码呢?
  6. [css] 简述下你理解的优雅降级和渐进增强
  7. [css] 说说你对line-height是如何理解的?
  8. 前端学习(2705):重读vue电商网站26之路由导航守卫控制访问权限
  9. 前端学习(2580):提升开发效率的工具
  10. 工作66:动态生成二维码