拓扑排序-体育课测验(二)

目录

一、问题描述

二、解答思路

三、代码实现

四、刷题链接


一、问题描述

二、解答思路

        拓扑排序:

        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;
    }
    
}

四、刷题链接

体育课测验(二)_牛客题霸_牛客网

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值