为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode857. 雇佣 K 名工人的最低成本 | Minimum Cost to Hire K Workers

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10594768.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i].

Now we want to hire exactly K workers to form a paid group.  When hiring a group of K workers, we must pay them according to the following rules:

  1. Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
  2. Every worker in the paid group must be paid at least their minimum wage expectation.

Return the least amount of money needed to form a paid group satisfying the above conditions. 

Example 1:

Input: quality = [10,20,5], wage = [70,50,30], K = 2
Output: 105.00000
Explanation: We pay 70 to 0-th worker and 35 to 2-th worker.

Example 2:

Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
Output: 30.66667
Explanation: We pay 4 to 0-th worker, 13.33333 to 2-th and 3-th workers seperately.  

Note:

  1. 1 <= K <= N <= 10000, where N = quality.length = wage.length
  2. 1 <= quality[i] <= 10000
  3. 1 <= wage[i] <= 10000
  4. Answers within 10^-5 of the correct answer will be considered correct.

有 N 名工人。 第 i 名工人的工作质量为 quality[i] ,其最低期望工资为 wage[i] 。

现在我们想雇佣 K 名工人组成一个工资组。在雇佣 一组 K 名工人时,我们必须按照下述规则向他们支付工资:

  1. 对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
  2. 工资组中的每名工人至少应当得到他们的最低期望工资。

返回组成一个满足上述条件的工资组至少需要多少钱。 

示例 1:

输入: quality = [10,20,5], wage = [70,50,30], K = 2
输出: 105.00000
解释: 我们向 0 号工人支付 70,向 2 号工人支付 35。

示例 2:

输入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
输出: 30.66667
解释: 我们向 0 号工人支付 4,向 2 号和 3 号分别支付 13.33333。 

提示:

  1. 1 <= K <= N <= 10000,其中 N = quality.length = wage.length
  2. 1 <= quality[i] <= 10000
  3. 1 <= wage[i] <= 10000
  4. 与正确答案误差在 10^-5 之内的答案将被视为正确的。

260ms
  1 class Solution {
  2     func mincostToHireWorkers(_ quality: [Int], _ wage: [Int], _ K: Int) -> Double {
  3   var workers: [(wage: Int, quality: Int)] = []
  4         
  5         for i in 0..<quality.count {
  6             workers.append((wage[i], quality[i]))
  7         }
  8         // Sort all workers with their expected ratio
  9         workers.sort { Double($0.wage) / Double($0.quality) < Double($1.wage) / Double($1.quality) } // O(n*logn)
 10         
 11         var heap = Heap(sort: >)
 12         
 13         var totalWage = Double(Int.max)
 14         var totalQuality = 0
 15         
 16         for worker in workers {
 17             let currRatio = Double(worker.wage)/Double(worker.quality)
 18             //print(currRatio)
 19             heap.push(worker.quality)
 20             totalQuality += worker.quality
 21             //print("total quality:", totalQuality)
 22             if heap.count > K {
 23                 totalQuality -= heap.remove()!
 24             }
 25             if heap.count == K {
 26                 totalWage = min(totalWage, Double(totalQuality) * currRatio)
 27                 //print("current total wage:", totalWage)
 28             }
 29         }
 30         
 31         return totalWage
 32     }
 33 }
 34 
 35 // Implementation of heap
 36 public struct Heap {
 37     
 38     var elements: [Int] = []
 39     let sort: (Int, Int) -> Bool
 40     var isEmpty: Bool {
 41         return self.elements.isEmpty
 42     }
 43     
 44     var count: Int {
 45         return self.elements.count
 46     }
 47     
 48     func peek() -> Int? {
 49         return elements.first
 50     }
 51     
 52     init(sort: @escaping (Int, Int) -> Bool, elements: [Int] = []) {
 53         self.sort = sort
 54         self.elements = elements
 55         
 56         if !elements.isEmpty {
 57             for i in stride(from: elements.count/2 - 1, through: 0, by: -1) {
 58                 siftDown(from: i)
 59             }
 60         }
 61     }
 62     
 63     mutating func siftDown(from index: Int) {
 64         var parent = index
 65         while true {
 66             let left = leftIndex(of: parent)
 67             let right = rightIndex(of: parent)
 68             var candidate = parent
 69             if left < count && sort(elements[left], elements[candidate]) {
 70                 candidate = left
 71             }
 72             if right < count && sort(elements[right], elements[candidate]) {
 73                 candidate = right
 74             }
 75             if candidate == parent {
 76                 return
 77             }
 78             elements.swapAt(parent, candidate)
 79             parent = candidate
 80         }
 81     }
 82     
 83     mutating func siftUp(from index: Int) {
 84         var child = index
 85         var parent = parentIndex(of: child)
 86         while child > 0 && sort(elements[child], elements[parent]) {
 87             elements.swapAt(child, parent)
 88             child = parent
 89             parent = parentIndex(of: child)
 90         }
 91     }
 92     
 93     mutating func push(_ element: Int) {
 94         elements.append(element)
 95         siftUp(from: count-1)
 96     }
 97     
 98     mutating func remove() -> Int? {
 99         guard !isEmpty else { return nil }
100         elements.swapAt(0, count-1)
101         defer {
102             siftDown(from: 0)
103         }
104         return elements.popLast()
105     }
106     
107     func leftIndex(of index: Int) -> Int {
108         return (2 * index) + 1
109     }
110     
111     func rightIndex(of index: Int) -> Int {
112         return (2 * index) + 2
113     }
114     
115     func parentIndex(of index: Int) -> Int {
116         return (index - 1) / 2
117     }
118 }

276ms

  1 class Solution {
  2     func mincostToHireWorkers(_ quality: [Int], _ wage: [Int], _ K: Int) -> Double {
  3         var quaRatios = [(Int, Double)]()
  4         for i in 0..<quality.count {
  5             quaRatios.append((quality[i], Double(wage[i]) / Double(quality[i])))
  6         }
  7         quaRatios.sort { $0.1 < $1.1 }
  8         var pq = PriorityQueue<Int> { $0 > $1 }
  9         var sum = 0
 10         var result = Double(Int.max)
 11         for (qua, ratio) in quaRatios {
 12             sum += qua
 13             pq.enqueue(qua)
 14             if pq.count > K {
 15                 sum -= pq.dequeue()!
 16             }
 17             if pq.count == K {
 18                 result = min(result, ratio * Double(sum))
 19             }
 20         }
 21         return result
 22     }
 23 }
 24 
 25 public struct PriorityQueue<T> {
 26   fileprivate var heap: Heap<T>
 27 
 28   /*
 29     To create a max-priority queue, supply a > sort function. For a min-priority
 30     queue, use <.
 31   */
 32   public init(sort: @escaping (T, T) -> Bool) {
 33     heap = Heap(sort: sort)
 34   }
 35 
 36   public var isEmpty: Bool {
 37     return heap.isEmpty
 38   }
 39 
 40   public var count: Int {
 41     return heap.count
 42   }
 43 
 44   public func peek() -> T? {
 45     return heap.peek()
 46   }
 47 
 48   public mutating func enqueue(_ element: T) {
 49     heap.insert(element)
 50   }
 51 
 52   public mutating func dequeue() -> T? {
 53     return heap.remove()
 54   }
 55 
 56   /*
 57     Allows you to change the priority of an element. In a max-priority queue,
 58     the new priority should be larger than the old one; in a min-priority queue
 59     it should be smaller.
 60   */
 61   public mutating func changePriority(index i: Int, value: T) {
 62     return heap.replace(index: i, value: value)
 63   }
 64 }
 65 
 66 extension PriorityQueue where T: Equatable {
 67   public func index(of element: T) -> Int? {
 68     return heap.index(of: element)
 69   }
 70 }
 71 
 72 //
 73 //  Heap.swift
 74 //  Written for the Swift Algorithm Club by Kevin Randrup and Matthijs Hollemans
 75 //
 76 public struct Heap<T> {
 77   
 78   /** The array that stores the heap's nodes. */
 79   var nodes = [T]()
 80   
 81   /**
 82    * Determines how to compare two nodes in the heap.
 83    * Use '>' for a max-heap or '<' for a min-heap,
 84    * or provide a comparing method if the heap is made
 85    * of custom elements, for example tuples.
 86    */
 87   private var orderCriteria: (T, T) -> Bool
 88   
 89   /**
 90    * Creates an empty heap.
 91    * The sort function determines whether this is a min-heap or max-heap.
 92    * For comparable data types, > makes a max-heap, < makes a min-heap.
 93    */
 94   public init(sort: @escaping (T, T) -> Bool) {
 95     self.orderCriteria = sort
 96   }
 97   
 98   /**
 99    * Creates a heap from an array. The order of the array does not matter;
100    * the elements are inserted into the heap in the order determined by the
101    * sort function. For comparable data types, '>' makes a max-heap,
102    * '<' makes a min-heap.
103    */
104   public init(array: [T], sort: @escaping (T, T) -> Bool) {
105     self.orderCriteria = sort
106     configureHeap(from: array)
107   }
108   
109   /**
110    * Configures the max-heap or min-heap from an array, in a bottom-up manner.
111    * Performance: This runs pretty much in O(n).
112    */
113   private mutating func configureHeap(from array: [T]) {
114     nodes = array
115     for i in stride(from: (nodes.count/2-1), through: 0, by: -1) {
116       shiftDown(i)
117     }
118   }
119   
120   public var isEmpty: Bool {
121     return nodes.isEmpty
122   }
123   
124   public var count: Int {
125     return nodes.count
126   }
127   
128   /**
129    * Returns the index of the parent of the element at index i.
130    * The element at index 0 is the root of the tree and has no parent.
131    */
132   @inline(__always) internal func parentIndex(ofIndex i: Int) -> Int {
133     return (i - 1) / 2
134   }
135   
136   /**
137    * Returns the index of the left child of the element at index i.
138    * Note that this index can be greater than the heap size, in which case
139    * there is no left child.
140    */
141   @inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int {
142     return 2*i + 1
143   }
144   
145   /**
146    * Returns the index of the right child of the element at index i.
147    * Note that this index can be greater than the heap size, in which case
148    * there is no right child.
149    */
150   @inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int {
151     return 2*i + 2
152   }
153   
154   /**
155    * Returns the maximum value in the heap (for a max-heap) or the minimum
156    * value (for a min-heap).
157    */
158   public func peek() -> T? {
159     return nodes.first
160   }
161   
162   /**
163    * Adds a new value to the heap. This reorders the heap so that the max-heap
164    * or min-heap property still holds. Performance: O(log n).
165    */
166   public mutating func insert(_ value: T) {
167     nodes.append(value)
168     shiftUp(nodes.count - 1)
169   }
170   
171   /**
172    * Adds a sequence of values to the heap. This reorders the heap so that
173    * the max-heap or min-heap property still holds. Performance: O(log n).
174    */
175   public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
176     for value in sequence {
177       insert(value)
178     }
179   }
180   
181   /**
182    * Allows you to change an element. This reorders the heap so that
183    * the max-heap or min-heap property still holds.
184    */
185   public mutating func replace(index i: Int, value: T) {
186     guard i < nodes.count else { return }
187     
188     remove(at: i)
189     insert(value)
190   }
191   
192   /**
193    * Removes the root node from the heap. For a max-heap, this is the maximum
194    * value; for a min-heap it is the minimum value. Performance: O(log n).
195    */
196   @discardableResult public mutating func remove() -> T? {
197     guard !nodes.isEmpty else { return nil }
198     
199     if nodes.count == 1 {
200       return nodes.removeLast()
201     } else {
202       // Use the last node to replace the first one, then fix the heap by
203       // shifting this new first node into its proper position.
204       let value = nodes[0]
205       nodes[0] = nodes.removeLast()
206       shiftDown(0)
207       return value
208     }
209   }
210   
211   /**
212    * Removes an arbitrary node from the heap. Performance: O(log n).
213    * Note that you need to know the node's index.
214    */
215   @discardableResult public mutating func remove(at index: Int) -> T? {
216     guard index < nodes.count else { return nil }
217     
218     let size = nodes.count - 1
219     if index != size {
220       nodes.swapAt(index, size)
221       shiftDown(from: index, until: size)
222       shiftUp(index)
223     }
224     return nodes.removeLast()
225   }
226   
227   /**
228    * Takes a child node and looks at its parents; if a parent is not larger
229    * (max-heap) or not smaller (min-heap) than the child, we exchange them.
230    */
231   internal mutating func shiftUp(_ index: Int) {
232     var childIndex = index
233     let child = nodes[childIndex]
234     var parentIndex = self.parentIndex(ofIndex: childIndex)
235     
236     while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
237       nodes[childIndex] = nodes[parentIndex]
238       childIndex = parentIndex
239       parentIndex = self.parentIndex(ofIndex: childIndex)
240     }
241     
242     nodes[childIndex] = child
243   }
244   
245   /**
246    * Looks at a parent node and makes sure it is still larger (max-heap) or
247    * smaller (min-heap) than its childeren.
248    */
249   internal mutating func shiftDown(from index: Int, until endIndex: Int) {
250     let leftChildIndex = self.leftChildIndex(ofIndex: index)
251     let rightChildIndex = leftChildIndex + 1
252     
253     // Figure out which comes first if we order them by the sort function:
254     // the parent, the left child, or the right child. If the parent comes
255     // first, we're done. If not, that element is out-of-place and we make
256     // it "float down" the tree until the heap property is restored.
257     var first = index
258     if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
259       first = leftChildIndex
260     }
261     if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
262       first = rightChildIndex
263     }
264     if first == index { return }
265     
266     nodes.swapAt(index, first)
267     shiftDown(from: first, until: endIndex)
268   }
269   
270   internal mutating func shiftDown(_ index: Int) {
271     shiftDown(from: index, until: nodes.count)
272   }
273   
274 }
275 
276 // MARK: - Searching
277 extension Heap where T: Equatable {
278   
279   /** Get the index of a node in the heap. Performance: O(n). */
280   public func index(of node: T) -> Int? {
281     return nodes.index(where: { $0 == node })
282   }
283   
284   /** Removes the first occurrence of a node from the heap. Performance: O(n log n). */
285   @discardableResult public mutating func remove(node: T) -> T? {
286     if let index = index(of: node) {
287       return remove(at: index)
288     }
289     return nil
290   }  
291 }

Runtime: 304 ms
Memory Usage: 20 MB
  1 class Solution {
  2     func mincostToHireWorkers(_ quality: [Int], _ wage: [Int], _ K: Int) -> Double {
  3         var workers:[[Double]] = [[Double]]()
  4         for i in 0..<quality.count
  5         {
  6             workers.append([Double(wage[i]) / Double(quality[i]), Double(quality[i])])
  7         }
  8         workers.sort(by:{(a:[Double],b:[Double]) -> Bool in
  9                         if a[0] == b[0]
 10                         {
 11                             return a[1] <= b[1]
 12                         }
 13                         else
 14                         {
 15                             return a[0] < b[0]
 16                         }})
 17         var res:Double = DBL_MAX
 18         var qsum:Double = 0
 19         var pq: PriorityQueue<Int> = PriorityQueue<Int>(false,[Int]())
 20         for worker in workers
 21         {
 22             let num:Double = worker[1]
 23             qsum += num
 24             pq.push(Int(num))
 25             if pq.count > K 
 26             {
 27                 qsum -= Double(pq.pop()!)                
 28             }
 29             if pq.count == K
 30             {
 31                 res = min(res, qsum * worker[0])
 32             }
 33         }
 34         return res
 35     }
 36 }
 37 
 38 public struct PriorityQueue<T: Comparable> {    
 39     fileprivate var heap = [T]()
 40     private let ordered: (T, T) -> Bool
 41     
 42     //创建具有给定顺序的新PriorityQueue。
 43     //order:true:降序 | false:升序
 44     //StartingValues:用于初始化PriorityQueue的元素数组。
 45     public init(_ ascending: Bool = false,_ startingValues: [T] = []) {
 46         self.init(order: ascending ? { $0 > $1 } : { $0 < $1 }, startingValues: startingValues)
 47     }
 48     
 49     public init(order: @escaping (T, T) -> Bool, startingValues: [T] = []) {
 50         ordered = order        
 51         //堆构造
 52         heap = startingValues
 53         var i = heap.count/2 - 1
 54         while i >= 0 {
 55             sink(i)
 56             i -= 1
 57         }
 58     }
 59     
 60     //优先级队列存储了多少个元素
 61     public var count: Int { return heap.count }
 62     
 63     //如果且仅当优先级队列为空时为true
 64     public var isEmpty: Bool { return heap.isEmpty }
 65     
 66     // 在优先级队列中添加新元素,复杂度:O(lg n)
 67     // element: 要插入优先级队列的元素.
 68     public mutating func push(_ element: T) {
 69         heap.append(element)
 70         swim(heap.count - 1)
 71     }
 72     
 73     //移除并返回具有最高优先级的元素(如果升序,则为最低优先级)。复杂度: O(lg n)
 74     //returns:优先级队列中优先级最高的元素,如果优先级队列为空,则为零。
 75     public mutating func pop() -> T? {        
 76         if heap.isEmpty { return nil }
 77         //增加了Swift 2兼容性
 78         if heap.count == 1 { return heap.removeFirst() } 
 79         //以便不使用同一位置的两个实例调用swap()
 80         heap.swapAt(0, heap.count - 1)
 81         let temp = heap.removeLast()
 82         sink(0)        
 83         return temp
 84     }
 85     
 86     private mutating func sink(_ index: Int) {
 87         var index = index
 88         while 2 * index + 1 < heap.count {            
 89             var j = 2 * index + 1            
 90             if j < (heap.count - 1) && ordered(heap[j], heap[j + 1]) { j += 1 }
 91             if !ordered(heap[index], heap[j]) { break }            
 92             heap.swapAt(index, j)
 93             index = j
 94         }
 95     }
 96     
 97     private mutating func swim(_ index: Int) {
 98         var index = index
 99         while index > 0 && ordered(heap[(index - 1) / 2], heap[index]) {
100             heap.swapAt((index - 1) / 2, index)
101             index = (index - 1) / 2
102         }
103     }
104 }

332ms

  1 class Solution {
  2     func mincostToHireWorkers(_ quality: [Int], _ wage: [Int], _ K: Int) -> Double {
  3         var workers = [(Int, Double)]()
  4         for i in 0..<quality.count {
  5             workers.append((quality[i], Double(wage[i]) / Double(quality[i])))
  6         }
  7         workers = workers.sorted {
  8             $0.1 < $1.1
  9         }
 10         
 11         var heap = Heap<Int>(elements: [], priorityFunction: >)
 12         var total = 0, res = Double.infinity
 13         for (quality, ratio) in workers {
 14             if heap.count == K {
 15                 if let top = heap.dequeue() {
 16                     total -= top
 17                 }
 18             }
 19             
 20             heap.enqueue(quality)
 21             total += quality
 22             if heap.count == K {
 23                 res = min(res, Double(total) * ratio)
 24             }
 25         }
 26         
 27         return res
 28     }
 29 }
 30 
 31 struct Heap<Element>
 32 {
 33     var elements : [Element]
 34     let priorityFunction : (Element, Element) -> Bool
 35 
 36     init(elements: [Element] = [], priorityFunction: @escaping (Element, Element) -> Bool) {
 37         self.elements = elements
 38         self.priorityFunction = priorityFunction
 39         buildHeap()
 40     }
 41 
 42     mutating func buildHeap() {
 43         for index in (0 ..< count / 2).reversed() {
 44             siftDown(elementAtIndex: index)
 45         }
 46     }
 47     
 48     var isEmpty : Bool { return elements.isEmpty }
 49     var count : Int { return elements.count }
 50 
 51     func peek() -> Element? {
 52         return elements.first
 53     }
 54 
 55     mutating func enqueue(_ element: Element) {
 56         elements.append(element)
 57         siftUp(elementAtIndex: count - 1)
 58     }
 59 
 60     mutating func siftUp(elementAtIndex index: Int) {
 61         let parent = parentIndex(of: index)
 62         guard !isRoot(index),
 63             isHigherPriority(at: index, than: parent)
 64             else { return }
 65         swapElement(at: index, with: parent)
 66         siftUp(elementAtIndex: parent)
 67     }
 68 
 69     mutating func dequeue() -> Element? {
 70         guard !isEmpty
 71             else { return nil }
 72         swapElement(at: 0, with: count - 1)
 73         let element = elements.removeLast()
 74         if !isEmpty {
 75             siftDown(elementAtIndex: 0)
 76         }
 77         return element
 78     }
 79     
 80     mutating func siftDown(elementAtIndex index: Int) {
 81         let childIndex = highestPriorityIndex(for: index)
 82         if index == childIndex {
 83             return
 84         }
 85         swapElement(at: index, with: childIndex)
 86         siftDown(elementAtIndex: childIndex)
 87     }
 88 
 89     // Helper functions
 90     
 91     func isRoot(_ index: Int) -> Bool {
 92         return index == 0
 93     }
 94     
 95     func leftChildIndex(of index: Int) -> Int {
 96         return (2 * index) + 1
 97     }
 98     
 99     func rightChildIndex(of index: Int) -> Int {
100         return (2 * index) + 2
101     }
102     
103     func parentIndex(of index: Int) -> Int {
104         return (index - 1) / 2
105     }
106     
107     func isHigherPriority(at firstIndex: Int, than secondIndex: Int) -> Bool {
108         return priorityFunction(elements[firstIndex], elements[secondIndex])
109     }
110     
111     func highestPriorityIndex(of parentIndex: Int, and childIndex: Int) -> Int {
112         guard childIndex < count && isHigherPriority(at: childIndex, than: parentIndex)
113             else { return parentIndex }
114         return childIndex
115     }
116     
117     func highestPriorityIndex(for parent: Int) -> Int {
118         return highestPriorityIndex(of: highestPriorityIndex(of: parent, and: leftChildIndex(of: parent)), and: rightChildIndex(of: parent))
119     }
120     
121     mutating func swapElement(at firstIndex: Int, with secondIndex: Int) {
122         guard firstIndex != secondIndex
123             else { return }
124         elements.swapAt(firstIndex, secondIndex)
125     }
126 }
127 
128 // A bonus extra for you: two extra functions, if the Element type is Equatable
129 extension Heap where Element : Equatable {
130     
131     // This function allows you to remove an element from the heap, in a similar way to how you would dequeue the root element.
132     mutating func remove(_ element: Element) {
133         guard let index = elements.index(of: element)
134             else { return }
135         swapElement(at: index, with: count - 1)
136         elements.remove(at: count - 1)
137         siftDown(elementAtIndex: index)
138     }
139 
140     // This function allows you to 'boost' an element, by sifting the element up the heap. You might do this if the element is already in the heap, but its priority has increased since it was enqueued.
141     mutating func boost(_ element: Element) {
142         guard let index = elements.index(of: element)
143             else { return }
144         siftUp(elementAtIndex: index)
145     }
146 }

376ms

 1 class Solution {
 2     class Heap {
 3         var arr = [0]
 4         var count: Int {
 5             return arr.count-1
 6         }
 7         
 8         var top: Int {
 9             return arr[1]
10         }
11         
12         func insert(_ num: Int) -> Void {
13             arr.append(num)
14             var i = arr.count-1
15             while i > 1 {
16                 if arr[i] > arr[i/2] {
17                     (arr[i], arr[i/2]) = (arr[i/2], arr[i])
18                 } else {
19                     break
20                 }
21                 i /= 2
22             }
23         }
24         
25         func pop() -> Int {
26             var ret = self.top
27             var last = arr.removeLast()
28             if self.count == 0 {
29                 return ret
30             }
31             
32             arr[1] = last
33             var i = 1
34             while i < arr.count {
35                 let left = i*2
36                 let right = i*2+1
37                 var next = i
38                 if left < arr.count && arr[left] > arr[next] {
39                     next = left
40                 }
41                 if right < arr.count && arr[right] > arr[next] {
42                     next = right
43                 }
44                 if i != next {
45                     (arr[i], arr[next]) = (arr[next], arr[i])
46                     i = next
47                 } else {
48                     break
49                 }
50                 
51             }
52             return ret
53         }
54     }
55     func mincostToHireWorkers(_ quality: [Int], _ wage: [Int], _ K: Int) -> Double {
56 
57         var n = quality.count
58         
59         var ranks = [Int](repeating: 0, count: n)
60         var ratios = [Double](repeating: 0.0, count: n)
61         
62         for i in 0..<n {
63             ranks[i] = i
64             ratios[i] = Double(wage[i])/Double(quality[i])
65         }
66         
67         ranks.sort { (i1, i2) in
68             if ratios[i1] == ratios[i2] {
69                 return quality[i1] < quality[i2]
70             } else {
71                 return ratios[i1] < ratios[i2]
72             }
73         }
74         
75         var sum = 0.0;
76         var heap = Heap()
77         
78         var ans = 1e9
79         
80         for rank in ranks {
81             heap.insert(quality[rank])
82             sum += Double(quality[rank])
83             if heap.count > K {
84                 var maxQ = heap.pop()
85                 sum -= Double(maxQ)
86             }
87             if heap.count == K {
88                 // print(ans, sum, ratios[rank])
89                 ans = min(ans, sum*ratios[rank])
90             }
91         }
92         return ans        
93     }
94 }

 

posted @ 2019-03-25 16:55  为敢技术  阅读(359)  评论(0编辑  收藏  举报