java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 |
---|
这道题是207题的衍生题,代码完全一样,具体解析看207题即可,这里不做过多赘述了。
🏆LeetCode207. 课程表(拓扑排序)https://blog.csdn.net/grd_java/article/details/137561889 |
---|
深度优先遍历但不进行逆拓扑排序(不用栈)
解题思路:时间复杂度O( m + n m+n m+n),空间复杂度O( m + n m+n m+n)n是顶点数,m是边的数量 |
---|
- 有了207题的基础,我们知道,深度优先遍历的拓扑排序输出结果是逆拓扑排序
- 如果我们想要正着输出,目前经典的解决方法,是先将结果放入栈中,最后完成排序后,再次出栈完成输出,实现逆拓扑排序反转效果
- 但是我们不使用栈如何实现呢?那就是逆中逆的思路
- 我们保存所有顶点的直接前驱顶点(指向它的顶点),然后逆过了,从每个顶点向上深度优先遍历,将它所有的前驱顶点处理完成,当前顶点就是0入度顶点
- 这样就完成了深度优先遍历,直接按照正拓扑排序顺序输出的效果
- 具体可以看207题的解析,有详细案例
class Solution {static class Node {Node next;int val;public Node(){this.val = -1;}public Node(int val){this.val = val;}public Node(int val,Node next){this.val = val;this.next = next;}}Node[] corses;int[] visited;int[] ans;int ansIndex;public int[] findOrder(int numCourses, int[][] prerequisites) {corses = new Node[numCourses];visited = new int[numCourses];ans = new int[numCourses];ansIndex = 0;for(int[] corse:prerequisites){corses[corse[0]]=new Node(corse[1],corses[corse[0]]);}for(int i = 0; i < numCourses; i++){if(!dfs(i)) return new int[]{};}return ans;}private boolean dfs(int i){if(visited[i] == 2)return true;if(visited[i] == 1)return false;visited[i] = 1;Node node = corses[i];while(node!=null){if(!dfs(node.val)) return false;node = node.next;}visited[i] = 2;ans[ansIndex++] = i;return true;}
}