★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:爲敢(WeiGanTechnologies)
➤我的域名:https://www.zengqiang.org
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-ynfimbqs-dx.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
There are n
items each belonging to zero or one of m
groups where group[i]
is the group that the i
-th item belongs to and it's equal to -1
if the i
-th item belongs to no group. The items and the groups are zero indexed.git
Return a sorted list of the items such that:github
beforeItems[i]
is a list containing all the items that should come before the i
-th item in the sorted array (to the left of the i
-th item).Return any solution if there is more than one solution and return an empty list if there is no solution.微信
Example 1:app
Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3,6],[],[],[]] Output: [6,3,4,1,5,2,0,7]
Example 2:post
Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3],[],[4],[]] Output: [] Explanation: This is the same as example 1 except that 4 needs to be before 6 in the sorted list.
Constraints:spa
1 <= m <= n <= 3*10^4
group.length == beforeItems.length == n
-1 <= group[i] <= m-1
0 <= beforeItems[i].length <= n-1
0 <= beforeItems[i][j] <= n-1
i != beforeItems[i][j]
公司共有 n
個項目和 m
個小組,每一個項目要不沒有歸屬,要不就由其中的一個小組負責。code
咱們用 group[i]
表明第 i
個項目所屬的小組,若是這個項目目前無人接手,那麼 group[i]
就等於 -1
。(項目和小組都是從零開始編號的)htm
請你幫忙按要求安排這些項目的進度,並返回排序後的項目列表:blog
beforeItems
來表示,其中 beforeItems[i]
表示在進行第 i
個項目前(位於第 i
個項目左側)應該完成的全部項目。結果要求:
若是存在多個解決方案,只須要返回其中任意一個便可。
若是沒有合適的解決方案,就請返回一個 空列表。
示例 1:
輸入:n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3,6],[],[],[]] 輸出:[6,3,4,1,5,2,0,7]
示例 2:
輸入:n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3],[],[4],[]] 輸出:[] 解釋:與示例 1 大體相同,可是在排序後的列表中,4 必須放在 6 的前面。
提示:
1 <= m <= n <= 3*10^4
group.length == beforeItems.length == n
-1 <= group[i] <= m-1
0 <= beforeItems[i].length <= n-1
0 <= beforeItems[i][j] <= n-1
i != beforeItems[i][j]
1 class Solution { 2 func sortItems(_ n: Int, _ m: Int, _ group: [Int], _ beforeItems: [[Int]]) -> [Int] { 3 var group = group 4 var ret:[Int] = [Int]() 5 //the vector stores the followers of the key which is the group id 6 var rules_between_groups:[Int:[Int]] = [Int:[Int]]() 7 //the key is the the group id, the value has similar structure as rules_between_groups 8 var rules_in_group:[Int:[Int:[Int]]] = [Int:[Int:[Int]]]() 9 var mm:Int = m 10 for i in 0..<group.count 11 { 12 //asign group ids for the no-group items 13 if group[i] == -1 {group[i] = mm++} 14 15 } 16 //parse the following/followed (beforeItems) rules 17 for i in 0..<beforeItems.count 18 { 19 for j in 0..<beforeItems[i].count 20 { 21 if group[beforeItems[i][j]] == group[i] 22 { 23 let gg:Int = group[i] 24 rules_in_group[gg,default:[Int:[Int]]()][beforeItems[i][j],default:[Int]()].append(i) 25 } 26 else 27 { 28 rules_between_groups[group[beforeItems[i][j]],default:[Int]()].append(group[i]) 29 } 30 } 31 } 32 //to remove the duplicated group id 33 var groups:Set<Int> = Set<Int>() 34 //key is the group id, vector stores the items 35 var items_by_group:[Int:[Int]] = [Int:[Int]]() 36 for i in 0..<group.count 37 { 38 groups.insert(group[i]) 39 items_by_group[group[i],default:[Int]()].append(i) 40 } 41 //vector of unique group ids 42 var vgroup:[Int] = Array(groups) 43 if !applyRules(&vgroup,&rules_between_groups) {return ret} 44 for i in 0..<m 45 { 46 if !applyRules(&items_by_group[i,default:[Int]()], &rules_in_group[i,default:[Int:[Int]]()]) 47 { 48 return ret 49 } 50 } 51 for gg in vgroup 52 { 53 for ii in items_by_group[gg,default:[Int]()] 54 { 55 ret.append(ii) 56 } 57 } 58 return ret 59 } 60 61 func applyRules(_ eles:inout [Int],_ rules:inout [Int:[Int]]) -> Bool 62 { 63 //toplogical sort 64 //id -> indegree number 65 var indegree:[Int:Int] = [Int:Int]() 66 for ele in eles 67 { 68 indegree[ele] = 0 69 } 70 eles.removeAll() 71 //calculate the indegrees 72 for valu in rules.values 73 { 74 for i in 0..<valu.count 75 { 76 indegree[valu[i],default:0] += 1 77 } 78 } 79 while(indegree.count > 0) 80 { 81 let start:Int = eles.count 82 for (key,val) in indegree 83 { 84 if val == 0 85 { 86 eles.append(key) 87 for aa in rules[key,default:[Int]()] 88 { 89 indegree[aa,default:0] -= 1 90 } 91 } 92 } 93 let stop:Int = eles.count 94 for i in start..<stop 95 { 96 indegree[eles[i]] = nil 97 } 98 if start == stop 99 { 100 return false 101 } 102 } 103 return true 104 } 105 } 106 107 /*擴展Int類,實現自增++、自減--運算符*/ 108 extension Int{ 109 //後綴++:先執行表達式後再自增 110 static postfix func ++(num:inout Int) -> Int { 111 //輸入輸出參數num 112 let temp = num 113 //num加1 114 num += 1 115 //返回加1前的數值 116 return temp 117 } 118 }