什么是拓扑排序?
把这样一个 有向无环图 变成 线性的排序 就叫 拓扑排序。
代码来源:
https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix/solution/zhi-jie-tao-yong-tuo-bu-pai-xu-mo-ban-mei-you-ji-q/
329.矩阵中的最长路径
class Solution {
public int longestIncreasingPath(int[][] matrix) {
if (matrix==null||matrix.length==0){
return 0;
}
int[][] count = new int[matrix.length][matrix[0].length];
int[][] direction = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
//统计每个点的入度用count数组保存,因为是递增,所以如果在上下左右,每发现一个比当前点小的数,当前点入度+1
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
for (int[] d : direction) {
if (longestIncreasingPathVerify(matrix, i + d[0], j + d[1]) && matrix[i + d[0]][j + d[1]] < matrix[i][j]) {
count[i][j]++;
}
}
}
}
Deque<int[]> deque = new LinkedList<>();
//count数组中所有入度为0的点加入队列
for (int i = 0; i < count.length; i++) {
for (int j = 0; j < count[i].length; j++) {
if (count[i][j] == 0) {
deque.add(new int[]{i, j});
}
}
}
int ans = 0;
while (!deque.isEmpty()) {
ans++;
//这个跟课程表I那个题不一样,需要一层一层的出列,而不是一个一个的出,因为课程表那个不关心队列长度
for (int size = deque.size(); size > 0; size--) {
int[] poll = deque.poll();
for (int[] d : direction) {
if (longestIncreasingPathVerify(matrix, poll[0] + d[0], poll[1] + d[1]) && matrix[poll[0] + d[0]][poll[1] + d[1]] > matrix[poll[0]][poll[1]]) {
if (--count[poll[0] + d[0]][poll[1] + d[1]] == 0) {
deque.add(new int[]{poll[0] + d[0], poll[1] + d[1]});
}
}
}
}
}
return ans;
}
private boolean longestIncreasingPathVerify(int[][] matrix, int i, int j) {
return i >= 0 && j >= 0 && i < matrix.length && j < matrix[i].length;
}
}
207.课程表
经典做法:
找出入度为0的点,建立邻接表,入队再出队即可。
作者:jyd
链接:https://leetcode-cn.com/problems/course-schedule/solution/course-schedule-tuo-bu-pai-xu-bfsdfsliang-chong-fa/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
int[] indegrees = new int[numCourses];
List<List<Integer>> adjacency = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
for(int i = 0; i < numCourses; i++)
adjacency.add(new ArrayList<>());
// Get the indegree and adjacency of every course.
for(int[] cp : prerequisites) {
indegrees[cp[0]]++;
adjacency.get(cp[1]).add(cp[0]);
}
// Get all the courses with the indegree of 0.
for(int i = 0; i < numCourses; i++)
if(indegrees[i] == 0) queue.add(i);
// BFS TopSort.
while(!queue.isEmpty()) {
int pre = queue.poll();
numCourses--;
for(int cur : adjacency.get(pre))
if(--indegrees[cur] == 0) queue.add(cur);
}
return numCourses == 0;
}
}
329.矩阵中的最长递增路径(多方法dfs/dp/拓扑排序)
记录出度的值,也就是每个点周围有几个比他大的,对每个出度为0的点,进行4个方向的遍历,出度不断地减,不断的循环,每循环一次就height++,直到最后容器里没有度为0的值,也就是,最后的点都有比自己小的点。
// Topological Sort Based Solution
// An Alternative Solution
public class Solution {
private static final int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
private int m, n;
public int longestIncreasingPath(int[][] grid) {
int m = grid.length;
if (m == 0) return 0;
int n = grid[0].length;
// padding the matrix with zero as boundaries
// assuming all positive integer, otherwise use INT_MIN as boundaries
int[][] matrix = new int[m + 2][n + 2];
for (int i = 0; i < m; ++i)
System.arraycopy(grid[i], 0, matrix[i + 1], 1, n);
// calculate outdegrees
int[][] outdegree = new int[m + 2][n + 2];
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
for (int[] d: dir)
if (matrix[i][j] < matrix[i + d[0]][j + d[1]])
outdegree[i][j]++;
// find leaves who have zero out degree as the initial level
n += 2;
m += 2;
List<int[]> leaves = new ArrayList<>();
for (int i = 1; i < m - 1; ++i)
for (int j = 1; j < n - 1; ++j)
if (outdegree[i][j] == 0) leaves.add(new int[]{i, j});
// remove leaves level by level in topological order
int height = 0;
while (!leaves.isEmpty()) {
height++;
List<int[]> newLeaves = new ArrayList<>();
for (int[] node : leaves) {
for (int[] d:dir) {
int x = node[0] + d[0], y = node[1] + d[1];
if (matrix[node[0]][node[1]] > matrix[x][y])
if (--outdegree[x][y] == 0)
newLeaves.add(new int[]{x, y});
}
}
leaves = newLeaves;
}
return height;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix/solution/ju-zhen-zhong-de-zui-chang-di-zeng-lu-jing-by-leet/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。