首页 > 试题广场 >

体育课测验(二)

[编程题]体育课测验(二)
  • 热度指数:417 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
体育课共有numProject个考核项目,编号为0numProject - 1,考核中每两个项目被划分为一组得到分组数组,现规定若想完成项目,必须先完成。保证所有分组互不相同,若分组情况能顺利完成考核,请返回任意的一个完成顺序,否则返回空数组
数据范围:

示例1

输入

3,[[2,1]]

输出

[1,2,0]

说明

要先完成1号项目,再完成2号项目,而0号项目不受约束,故可以以1 2 0的顺序完成项目。  
示例2

输入

3,[[1,0], [0,1]]

输出

[]

说明

第一个分组要求先完成0号项目,再完成1号项目;而第二个分组要求先完成1号项目,再完成0号项目,自相矛盾,故不可以完成项目。  
这道题是典型的有向无环图处理(DAG),在处理DAG 的时候,要考虑是否存在多个DAG,就比如这道题,如果所有项目只能构成一个有向无环图,则入度为0的点只有一个,我们最终构建的结果也只有一个,如果是多个DAG的话,我们需要考虑每一个 DAG(即入度为0的点),然后构建出来, 如果多个DAG图有公共节点的话,公共节点的前驱节点的度为1,处理时,会对每个前驱节点处理,直到最后一个前驱节点处理完成,入度降为0,然后再处理公共节点的后继节点,后继节点入度也为1,处理一次度就降为0继续往下处理,直到全部处理完成,代码如下:
  public ArrayList<Integer> findOrder(int numProject, ArrayList<ArrayList<Integer>> groups) {
        // 使用邻接表表示图
        ArrayList<ArrayList<Integer>> adjList = new ArrayList<>();
        for (int i = 0; i < numProject; i++) {
            adjList.add(new ArrayList<>());
        }

        // 入度数组
        int[] indegree = new int[numProject];

        // 构建图
        for (ArrayList<Integer> group : groups) {
            int first = group.get(0);
            int second = group.get(1);
            adjList.get(second).add(first);
            indegree[first]++;
        }

        // 用于存储入度为零的节点的队列
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numProject; i++) {
            if (indegree[i] == 0) {
                queue.offer(i);
            }
        }

        // 结果列表,用于存储项目的完成顺序
        ArrayList<Integer> result = new ArrayList<>();

        // 处理队列
        /**
         *      公共节点的每个前驱节点度为1,在最后一个前驱节点处理完成时,
         *      公共节点的度降为0,继续处理公共节点的后继节点,公共节点的后继节点度为1,
         *      确保减1操作后度降为0,能正确加入队列,继续处理
         */
        while (!queue.isEmpty()) {
            int current = queue.poll();
            result.add(current);
            for (int neighbor : adjList.get(current)) {
                indegree[neighbor]--;
                if (indegree[neighbor] == 0) {
                    queue.offer(neighbor);
                }
            }
        }

        return result.size() == numProject ? result :  new ArrayList<>(); // 如果存在循环或未处理所有节点,则返回空列表
    }



发表于 2024-05-06 16:44:33 回复(1)

问题信息

难度:
1条回答 768浏览

热门推荐

通过挑战的用户

查看代码