1. 程式人生 > 實用技巧 >拓撲排序-1203. 專案管理。。。沒看懂

拓撲排序-1203. 專案管理。。。沒看懂

package Leetcode;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 公司共有n個專案和 m個小組,每個專案要不無人接手,要不就由 m 個小組之一負責。
 * 
 * group[i] 表示第i個專案所屬的小組,如果這個專案目前無人接手,那麼group[i]
 * 就等於-1。(專案和小組都是從零開始編號的)小組可能存在沒有接手任何專案的情況。
 * 
 * 請你幫忙按要求安排這些專案的進度,並返回排序後的專案列表:
 * 
 * 同一小組的專案,排序後在列表中彼此相鄰。 專案之間存在一定的依賴關係,我們用一個列表
 * beforeItems來表示,其中beforeItems[i]表示在進行第i個專案前(位於第 i個專案左側)應該完成的所有專案。
 * 如果存在多個解決方案,只需要返回其中任意一個即可。如果沒有合適的解決方案,就請返回一個 空列表 。
 
*/ //沒看懂 public class test1203 { public static void main(String[] args) { int n=8; int m=2; int []group={-1,-1,1,0,0,1,0,-1}; List<List<Integer>> beforeItems=new ArrayList<>(); for(int i=0;i<8;i++){ List<Integer> list=new ArrayList<>();
if(i==0||i==5||i==6||i==7){ beforeItems.add(new ArrayList()); }else if(i==1||i==3){ list.add(6); beforeItems.add(new ArrayList<>(list)); }else if(i==2){ list.add(5); beforeItems.add(
new ArrayList<>(list)); }else if(i==4){ list.add(3); list.add(6); beforeItems.add(new ArrayList<>(list)); } } sortItems(n,m,group,beforeItems); } //拓撲排序 public static int[] sortItems(int n, int m, int[] group, List<List<Integer>> beforeItems) { List<List<Integer>> groupItem=new ArrayList<>(); for(int i=0;i<n+m;++i){ groupItem.add(new ArrayList<>()); } //組間和組內依賴圖 List<List<Integer>> groupGraph=new ArrayList(); for(int i=0;i<n+m;++i){ groupGraph.add(new ArrayList<>()); } List<List<Integer>> itemGraph=new ArrayList<>(); for(int i=0;i<n;++i){ itemGraph.add(new ArrayList<>()); } //組間和組內入度陣列 int []groupDegree=new int[n+m]; int []itemDegree=new int[n]; List<Integer> id=new ArrayList<>(); for(int i=0;i<n+m;++i){ id.add(i); } //// 給未分配的 item 分配一個 groupId int leftId=m; for(int i=0;i<n;++i){ if(group[i]==-1){ group[i]=leftId; leftId++; } groupItem.get(group[i]).add(i); } // 依賴關係建圖 for (int i = 0; i < n; ++i) { int curGroupId = group[i]; for (int item : beforeItems.get(i)) { int beforeGroupId = group[item]; if (beforeGroupId == curGroupId) { itemDegree[i] += 1; itemGraph.get(item).add(i); } else { groupDegree[curGroupId] += 1; groupGraph.get(beforeGroupId).add(curGroupId); } } } // 組間拓撲關係排序 List<Integer> groupTopSort = topSort(groupDegree, groupGraph, id); if (groupTopSort.size() == 0) { return new int[0]; } int[] ans = new int[n]; int index = 0; // 組內拓撲關係排序 for (int curGroupId : groupTopSort) { int size = groupItem.get(curGroupId).size(); if (size == 0) { continue; } List<Integer> res = topSort(itemDegree, itemGraph, groupItem.get(curGroupId)); if (res.size() == 0) { return new int[0]; } for (int item : res) { ans[index++] = item; } } return ans; } public static List<Integer> topSort(int[] deg, List<List<Integer>> graph, List<Integer> items) { Queue<Integer> queue = new LinkedList<Integer>(); for (int item : items) { if (deg[item] == 0) { queue.offer(item); } } List<Integer> res = new ArrayList<Integer>(); while (!queue.isEmpty()) { int u = queue.poll(); res.add(u); for (int v : graph.get(u)) { if (--deg[v] == 0) { queue.offer(v); } } } return res.size() == items.size() ? res : new ArrayList<Integer>(); } }