[Swift]LeetCode1167. 连接棒材的最低费用 | Minimum Cost to Connect Sticks
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(www.zengqiang.org)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/11407050.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You have some sticks
with positive integer lengths.
You can connect any two sticks of lengths X
and Y
into one stick by paying a cost of X + Y
. You perform this action until there is one stick remaining.
Return the minimum cost of connecting all the given sticks
into one stick in this way.
Example 1:
Input: sticks = [2,4,3] Output: 14
Example 2:
Input: sticks = [1,8,3,5] Output: 30
Constraints:
1 <= sticks.length <= 10^4
1 <= sticks[i] <= 10^4
为了装修新房,你需要加工一些长度为正整数的棒材 sticks
。
如果要将长度分别为 X
和 Y
的两根棒材连接在一起,你需要支付 X + Y
的费用。 由于施工需要,你必须将所有棒材连接成一根。
返回你把所有棒材 sticks
连成一根所需要的最低费用。注意你可以任意选择棒材连接的顺序。
示例 1:
输入:sticks = [2,4,3] 输出:14 解释:先将 2 和 3 连接成 5,花费 5;再将 5 和 4 连接成 9;总花费为 14。
示例 2:
输入:sticks = [1,8,3,5] 输出:30
提示:
1 <= sticks.length <= 10^4
1 <= sticks[i] <= 10^4
1884 ms
1 class Solution { 2 func connectSticks(_ sticks: [Int]) -> Int { 3 var pq:PriorityQueue<Int> = PriorityQueue<Int> { $0 < $1 } 4 for v in sticks 5 { 6 pq.push(v) 7 } 8 var ans:Int = 0 9 while(pq.count > 1) 10 { 11 let x:Int = pq.pop()! 12 let y:Int = pq.pop()! 13 let sum:Int = x + y 14 ans += sum 15 pq.push(sum) 16 } 17 return ans 18 } 19 } 20 21 public struct PriorityQueue<T> { 22 fileprivate var heap: Heap<T> 23 public init(sort: @escaping (T, T) -> Bool) { 24 heap = Heap(sort: sort) 25 } 26 27 public var isEmpty: Bool { 28 return heap.isEmpty 29 } 30 31 public var count: Int { 32 return heap.count 33 } 34 35 public func peek() -> T? { 36 return heap.peek() 37 } 38 39 public mutating func push(_ element: T) { 40 heap.insert(element) 41 } 42 43 public mutating func pop() -> T? { 44 return heap.remove() 45 } 46 47 public mutating func changePriority(index i: Int, value: T) { 48 return heap.replace(index: i, value: value) 49 } 50 } 51 52 extension PriorityQueue where T: Equatable { 53 public func index(of element: T) -> Int? { 54 return heap.index(of: element) 55 } 56 } 57 58 public struct Heap<T> { 59 var nodes = [T]() 60 61 private var orderCriteria: (T, T) -> Bool 62 63 public init(sort: @escaping (T, T) -> Bool) { 64 self.orderCriteria = sort 65 } 66 67 public init(array: [T], sort: @escaping (T, T) -> Bool) { 68 self.orderCriteria = sort 69 configureHeap(from: array) 70 } 71 72 private mutating func configureHeap(from array: [T]) { 73 nodes = array 74 for i in stride(from: (nodes.count/2-1), through: 0, by: -1) { 75 shiftDown(i) 76 } 77 } 78 79 public var isEmpty: Bool { 80 return nodes.isEmpty 81 } 82 83 public var count: Int { 84 return nodes.count 85 } 86 87 @inline(__always) internal func parentIndex(ofIndex i: Int) -> Int { 88 return (i - 1) / 2 89 } 90 91 @inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int { 92 return 2*i + 1 93 } 94 95 @inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int { 96 return 2*i + 2 97 } 98 99 public func peek() -> T? { 100 return nodes.first 101 } 102 103 public mutating func insert(_ value: T) { 104 nodes.append(value) 105 shiftUp(nodes.count - 1) 106 } 107 108 public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T { 109 for value in sequence { 110 insert(value) 111 } 112 } 113 114 public mutating func replace(index i: Int, value: T) { 115 guard i < nodes.count else { return } 116 117 remove(at: i) 118 insert(value) 119 } 120 121 @discardableResult public mutating func remove() -> T? { 122 guard !nodes.isEmpty else { return nil } 123 124 if nodes.count == 1 { 125 return nodes.removeLast() 126 } else { 127 let value = nodes[0] 128 nodes[0] = nodes.removeLast() 129 shiftDown(0) 130 return value 131 } 132 } 133 134 @discardableResult public mutating func remove(at index: Int) -> T? { 135 guard index < nodes.count else { return nil } 136 137 let size = nodes.count - 1 138 if index != size { 139 nodes.swapAt(index, size) 140 shiftDown(from: index, until: size) 141 shiftUp(index) 142 } 143 return nodes.removeLast() 144 } 145 146 internal mutating func shiftUp(_ index: Int) { 147 var childIndex = index 148 let child = nodes[childIndex] 149 var parentIndex = self.parentIndex(ofIndex: childIndex) 150 151 while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) { 152 nodes[childIndex] = nodes[parentIndex] 153 childIndex = parentIndex 154 parentIndex = self.parentIndex(ofIndex: childIndex) 155 } 156 157 nodes[childIndex] = child 158 } 159 160 internal mutating func shiftDown(from index: Int, until endIndex: Int) { 161 let leftChildIndex = self.leftChildIndex(ofIndex: index) 162 let rightChildIndex = leftChildIndex + 1 163 164 var first = index 165 if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) { 166 first = leftChildIndex 167 } 168 if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) { 169 first = rightChildIndex 170 } 171 if first == index { return } 172 173 nodes.swapAt(index, first) 174 shiftDown(from: first, until: endIndex) 175 } 176 177 internal mutating func shiftDown(_ index: Int) { 178 shiftDown(from: index, until: nodes.count) 179 } 180 181 } 182 183 extension Heap where T: Equatable { 184 185 public func index(of node: T) -> Int? { 186 return nodes.firstIndex(where: { $0 == node }) 187 } 188 189 @discardableResult public mutating func remove(node: T) -> T? { 190 if let index = index(of: node) { 191 return remove(at: index) 192 } 193 return nil 194 } 195 }