★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-wcfbedpg-mc.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
We have a collection of rocks, each rock has a positive integer weight.node
Each turn, we choose the two heaviest rocks and smash them together. Suppose the stones have weights x
and y
with x <= y
. The result of this smash is:git
x == y
, both stones are totally destroyed;x != y
, the stone of weight x
is totally destroyed, and the stone of weight y
has new weight y-x
.At the end, there is at most 1 stone left. Return the weight of this stone (or 0 if there are no stones left.)github
Note:api
1 <= stones.length <= 30
1 <= stones[i] <= 1000
有一堆石頭,每塊石頭的重量都是正整數。微信
每一回合,從中選出兩塊最重的石頭,而後將它們一塊兒粉碎。假設石頭的重量分別爲 x
和 y
,且 x <= y
。那麼粉碎的可能結果以下:app
x == y
,那麼兩塊石頭都會被徹底粉碎;x != y
,那麼重量爲 x
的石頭將會徹底粉碎,而重量爲 y
的石頭新重量爲 y-x
。最後,最多隻會剩下一塊石頭。返回此石頭的重量。若是沒有石頭剩下,就返回 0
。this
提示:spa
1 <= stones.length <= 30
1 <= stones[i] <= 1000
8mscode
1 class Solution { 2 let heap = Heap<Int>(type: .max) 3 4 func lastStoneWeight(_ stones: [Int]) -> Int { 5 for stone in stones { 6 heap.insert(stone) 7 } 8 9 return helper() 10 } 11 12 private func helper() -> Int { 13 guard let a = heap.pop() else { return 0 } 14 guard let b = heap.pop() else { return a } 15 16 if a != b { 17 heap.insert(a - b) 18 } 19 20 return helper() 21 } 22 } 23 24 enum HeapType { 25 case min 26 case max 27 28 func compare<T: Comparable>(_ a: T, _ b: T) -> Bool { 29 switch self { 30 case .min: 31 return a < b 32 case .max: 33 return a > b 34 } 35 } 36 } 37 38 class Heap<T: Comparable> { 39 // MARK: - Properties & Init 40 var array: [T] 41 var type: HeapType 42 var nodeIndexUpdateHandler: ((Int) -> Void)? = nil 43 44 init(type: HeapType, array: [T] = []) { 45 self.type = type 46 self.array = array 47 48 guard !array.isEmpty else { return } 49 50 var i = (array.count - 1) / 2 51 while i >= 0 { 52 heapify(i) 53 i -= 1 54 } 55 } 56 57 // MARK: - APIs 58 59 var count: Int { 60 return array.count 61 } 62 63 // O[1] 64 func pop() -> T? { 65 guard let first = array.first else { 66 return nil 67 } 68 69 if let last = array.last { 70 array[0] = last 71 heapify(0) 72 } 73 74 array.removeLast() 75 76 return first 77 } 78 79 // O[1] 80 func peek() -> T? { 81 return array.first 82 } 83 84 // O[log(n)] 85 func insert(_ val: T) { 86 array.append(val) 87 nodeIndexUpdateHandler?(array.count - 1) 88 siftUp(array.count - 1) 89 } 90 91 // MARK: - Utilty Methods 92 func heapify(_ i: Int) { 93 var top = i 94 95 if let left = left(i), type.compare(array[left], array[top]) { 96 top = left 97 } 98 99 if let right = right(i), type.compare(array[right], array[top]) { 100 top = right 101 } 102 103 if top != i { 104 swapAt(i, top) 105 heapify(top) 106 } else { 107 nodeIndexUpdateHandler?(i) 108 } 109 } 110 111 func siftUp(_ i: Int) { 112 var parent = parentIndex(i) 113 var this = i 114 115 while let p = parent, type.compare(array[this], array[p]) { 116 swapAt(p, this) 117 parent = parentIndex(p) 118 this = p 119 } 120 } 121 122 func swapAt(_ i: Int, _ j: Int) { 123 array.swapAt(i, j) 124 nodeIndexUpdateHandler?(i) 125 nodeIndexUpdateHandler?(j) 126 } 127 128 func parentIndex(_ i: Int) -> Int? { 129 guard i > 0 else { return nil } 130 return (i - 1) / 2 131 } 132 133 func left(_ i: Int) -> Int? { 134 let left = i * 2 + 1 135 return left < array.count ? left : nil 136 } 137 138 func right(_ i: Int) -> Int? { 139 let right = i * 2 + 2 140 return right < array.count ? right : nil 141 } 142 }
1 class Solution { 2 func lastStoneWeight(_ stones: [Int]) -> Int { 3 var stones = stones 4 while (stones.count > 1) 5 { 6 stones = stones.sorted() 7 stones.append(abs(stones.popLast()! - stones.popLast()!)) 8 } 9 return stones[0] 10 } 11 }