跳至主要內容

任务调度


任务调度

题目

有N个任务,从0到N-1。每个任务都有一些先决条件任务,这些任务需要在调度之前完成。给定任务的数量和先决条件对的列表,找出是否有可能安排所有任务。

示例:

输入:Tasks=3, Prerequisites=[0,1], [1,2]
输出:[0, 1, 2]

解答

import java.util.*;

class TopologicalSort {
  public static List<Integer> sort(int vertices, int[][] edges) {
    List<Integer> sortedOrder = new ArrayList<>();
    if (vertices <= 0)
      return sortedOrder;

    // a. 初始化图
    HashMap<Integer, Integer> inDegree = new HashMap<>(); // 计算每个节点的入度
    HashMap<Integer, List<Integer>> graph = new HashMap<>(); // 邻接链表图
    for (int i = 0; i < vertices; i++) {
      inDegree.put(i, 0);
      graph.put(i, new ArrayList<Integer>());
    }

    // b. 构建图
    for (int i = 0; i < edges.length; i++) {
      int parent = edges[i][0], child = edges[i][1];
      graph.get(parent).add(child); // 将孩子添加到父结点的list中
      inDegree.put(child, inDegree.get(child) + 1); // 增加孩子的入度
    }

    // c. 找到所有的源节点,源节点入度为0
    Queue<Integer> sources = new LinkedList<>();
    for (Map.Entry<Integer, Integer> entry : inDegree.entrySet()) {
      if (entry.getValue() == 0)
        sources.add(entry.getKey());
    }

    // d. 对于每一个源节点,添加它到已排序list中,同时将它的所有孩子节点入度减一
    // 如果一个孩子节点的入度变成1,添加它到源队列中
    while (!sources.isEmpty()) {
      int vertex = sources.poll();
      sortedOrder.add(vertex);
      List<Integer> children = graph.get(vertex); // 获取该节点的子节点,并将入度减1
      for (int child : children) {
        inDegree.put(child, inDegree.get(child) - 1);
        if (inDegree.get(child) == 0)
          sources.add(child);
      }
    }

    return sortedOrder.size() == vertices;
  }

  public static void main(String[] args) {
    List<Integer> result = TopologicalSort.sort(4,
        new int[][] { new int[] { 3, 2 }, new int[] { 3, 0 }, new int[] { 2, 0 }, new int[] { 2, 1 } });
    System.out.println(result);

    result = TopologicalSort.sort(5, new int[][] { new int[] { 4, 2 }, new int[] { 4, 3 }, new int[] { 2, 0 },
        new int[] { 2, 1 }, new int[] { 3, 1 } });
    System.out.println(result);

    result = TopologicalSort.sort(7, new int[][] { new int[] { 6, 4 }, new int[] { 6, 2 }, new int[] { 5, 3 },
        new int[] { 5, 4 }, new int[] { 3, 0 }, new int[] { 3, 1 }, new int[] { 3, 2 }, new int[] { 4, 1 } });
    System.out.println(result);
  }
}
上次编辑于:
贡献者: Neil