[Swift]LeetCode1203. 項目管理 | Sort Items by Groups Respecting Dependencies

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:爲敢(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

  • The items that belong to the same group are next to each other in the sorted list.
  • There are some relations between these items where 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]

Runtime: 556 ms
Memory Usage: 28.7 MB
  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 }
相關文章
相關標籤/搜索