课程表||
· 题目描述:
· 思路:
第一步判断如果课程数为0,就直接返回一个空的数组。
定义一个长度为课程数的哈希表,第 i 行存放课程 i 的子女节点。
通过一个 flags数组来标记每个节点的被访问状态:
-
0表示该节点未被任何节点启动的 DFS 访问;
-
-1表示该节点已被其他节点启动的 DFS 访问;
-
1表示该节点已被当前节点启动的 DFS 访问。
将当前访问节点 i 对应 flags[i] 置 1,即标记其被本轮 DFS 访问过;
递归访问当前节点 i 的所有邻接节点 j,当发现环直接返回false。
若当前节点所有邻接节点已被遍历,并没有发现环,则将当前节点 flags[i] 置为 −1 并返回 true。
若整个图 DFS 结束并未发现环,节点 i 入栈并返回 true。
深度优先搜索每一个节点,判断图中是否有环,如果有直接返回一个空数组,
把结果存放在栈中,若中间始终没有出现环,最后依次出栈通过result 数组返回。
· 代码:
class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
if(numCourses==0)
{
return new int[0];
}
HashSet<Integer>[]hash=new HashSet[numCourses];
for(int i=0;i<numCourses;i++)
{
hash[i]=new HashSet<>();
}
for(int[]kk : prerequisites)
{
hash[kk[1]].add(kk[0]);
}
int []flags=new int[numCourses]; //标记数组
Stack<Integer>stack=new Stack<>(); //结果栈
for(int i=0;i<numCourses;i++)
{
if(!IsCycle(hash,flags,i,stack))
{
return new int[0];
}
}
int[]result=new int[numCourses];
for(int i=0;i<numCourses;i++)
{
result[i]=stack.pop();
}
return result;
}
private boolean IsCycle(HashSet<Integer>[]hash,int[]flags,int i,Stack<Integer>stack)
{
if(flags[i]==1)return false;
if(flags[i]==-1)return true;
flags[i]=1;
for(int j: hash[i])
{
if(!IsCycle(hash,flags,j,stack))return false;
}
flags[i]=-1;
stack.push(i);
return true;
}
}