• [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 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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 }
  • 相关阅读:
    manage.py migrate 报错
    pip安装django出错 Could not install packages due to an EnvironmentError: [Errno 13]
    利用beautifulsoup下载网页html代码中的css, js, img文件并保存
    itchat库微信自动回复祝福语
    关于阿里云Mysql分页查询不走索引的问题
    如何成为PHP程序员?
    Linux常用命令之scp
    PHP版本的区别与用法详解
    Linux常用命令之ftp
    Linux常用命令之权限管理
  • 原文地址:https://www.cnblogs.com/strengthen/p/10594768.html
Copyright © 2020-2023  润新知