目录
一、问题描述
二、解答思路
三、代码实现
四、刷题链接
一、问题描述
二、解答思路
拓扑排序:
1.设置一个入度数组,构建图的邻接矩阵的同时对入度数组进行初始化
2.执行结点个数次的循环,每次循环都统计入度数组中的入度为0的结点P,加入返回值数组中,同时在入度数组中把该结点标记删除(这里我通过赋值-1来标记的),然后更新以该结点P为起点连接的结点的入度减1。
3.执行完循环后查看入度数组内是否还存在入度不是-1的点,如果存在则证明有环,题目给出的序列不符合要求,返回空数组。
三、代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numProject int整型
* @param groups int整型ArrayList<ArrayList<>>
* @return int整型ArrayList
*/
public ArrayList<Integer> findOrder (int numProject, ArrayList<ArrayList<Integer>> groups) {
// 先构建有向图,然后判断是否有环
ArrayList<Integer> resArr=new ArrayList<>();
int[][] graph=new int[numProject][numProject];
//存放入度
int[] indegree=new int[numProject];
//初始化有向图和入度
for(int idx=0;idx<groups.size();idx++){
ArrayList<Integer> tmpArr=groups.get(idx);
graph[tmpArr.get(1)][tmpArr.get(0)]=1;
indegree[tmpArr.get(0)]++;
}
for(int i=0;i<graph.length;i++){
detectIndegree(indegree,graph,resArr);
}
//执行graph.length后再次检查resArr,如果不全是-1,就意味着出现了回路,返回空数组
for(int i=0;i<indegree.length;i++){
if(indegree[i]!=-1){
resArr.clear();
}
}
return resArr;
}
public boolean detectIndegree(int[] indegree,int[][] graph,ArrayList<Integer> resArr){
boolean allzero=true;
for(int i=0;i<graph.length;i++){
if(indegree[i]!=0&&indegree[i]!=-1){
allzero=false;
}else if(indegree[i]==0){
resArr.add(i);
indegree[i]=-1;//标记删除
//以i为前驱的结点入度-1
for(int j=0;j<graph.length;j++){
if(graph[i][j]==1){
indegree[j]--;
}
}
}else{//已删除结点略过
}
}
return allzero;
}
}
四、刷题链接
体育课测验(二)_牛客题霸_牛客网