文章目录
- 1.最小高度树
- 2.课程表二
- 3.矩阵中的最长递增路径
对于拓扑排序的理论知识没有找到好的资料,不妨先通过几道题目理解一下
1.最小高度树
310. 最小高度树 给定一棵包含n个节点的树,标记0到n-1,给定数字n和一个有n-1条无向边的edges列表。
可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树 。
目前理解的拓扑排序是通过入度获取树的最内层节点,该题目实际上就是寻找树的最内层节点
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
vector<int> res;
if(n==1) {
res.push_back(0);
return res;
}
vector<vector<int>> d(n,vector<int>());
vector<int> indegree(n,0);
for(auto v: edges){
d[v[0]].push_back(v[1]); d[v[1]].push_back(v[0]);
indegree[v[0]]++; indegree[v[1]]++;
}
queue<int> q;
for(int i=0;i<n;i++){
if(indegree[i]==1) q.push(i);
}
while (n>2) {
int num = (int)q.size();
n -= num;
for(int i=0;i<num;i++){
int j=q.front(); q.pop();
for(auto x:d[j]){
indegree[x]--;
if(indegree[x]==1) q.push(x);
}
}
}
while(!q.empty()){
res.push_back(q.front()); q.pop();
}
return res;
}
};
2.课程表二
210.课程表二 现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。
class Solution210 {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> edges;
vector<int> indeg;
vector<int> res;
edges.resize(numCourses);
indeg.resize(numCourses);
for(const auto& x: prerequisites){
edges[x[1]].push_back(x[0]);
indeg[x[0]]++;
}
queue<int> q;
for(int i=0;i<numCourses;i++){
if(indeg[i]==0) q.push(i);
}
int r = 0;
while (!q.empty()) {
int t = q.front();
res.push_back(t);
r++;
q.pop();
for(auto x: edges[t]){
indeg[x]--;
if(indeg[x]==0) q.push(x);
}
}
return r==numCourses? res: vector<int>();
}
};
3.矩阵中的最长递增路径
329. 矩阵中的最长递增路径 给定一个 m x n
整数矩阵 matrix
,找出其中 最长递增路径 的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。
这道题可以通过回溯的方式,这里记录下拓扑排序
- 考虑入度和出度都可以,代码使用入度计算
- 深度优先的方式,找到每一条递增路径的起始点,操作入度并更新相邻的入度
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix) {
int m=(int)matrix.size(), n=(int)matrix[0].size();
int res=0;
//int c4[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
vector<vector<int>> indegrees(m,vector<int>(n)); // indegrees
queue<pair<int, int>> q;
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
if(i-1>=0 && matrix[i-1][j]<matrix[i][j]) ++indegrees[i][j];
if(j-1>=0 && matrix[i][j-1]<matrix[i][j]) ++indegrees[i][j];
if(i+1<m && matrix[i+1][j]<matrix[i][j]) ++indegrees[i][j];
if(j+1<n && matrix[i][j+1]<matrix[i][j]) ++indegrees[i][j];
if(!indegrees[i][j]) q.push({i,j});
}
}
while (!q.empty()) {
++res;
int siz=(int)q.size();
//cout<<siz<<endl;
for(int a=0;a<siz;++a){
pair<int, int> p = q.front(); q.pop();
int i = p.first; int j=p.second;
if(i-1>=0 && matrix[i-1][j]>matrix[i][j]) {
--indegrees[i-1][j];
if(!indegrees[i-1][j]) q.push({i-1,j});
}
if(j-1>=0 && matrix[i][j-1]>matrix[i][j]){
--indegrees[i][j-1];
if(!indegrees[i][j-1]) q.push({i,j-1});
}
if(i+1<m && matrix[i+1][j]>matrix[i][j]) {
--indegrees[i+1][j];
if(!indegrees[i+1][j]) q.push({i+1,j});
}
if(j+1<n && matrix[i][j+1]>matrix[i][j]) {
--indegrees[i][j+1];
if(!indegrees[i][j+1]) q.push({i,j+1});
}
}
}
return res;
}
};