[Swift]LeetCode632. 最小区间 | Smallest Range
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10478921.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You have k
lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k
lists.
We define the range [a,b] is smaller than range [c,d] if b-a < d-c
or a < c
if b-a == d-c
.
Example 1:
Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] Output: [20,24] Explanation: List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. List 2: [0, 9, 12, 20], 20 is in range [20,24]. List 3: [5, 18, 22, 30], 22 is in range [20,24].
Note:
- The given list may contain duplicates, so ascending order means >= here.
- 1 <=
k
<= 3500 - -105 <=
value of elements
<= 105. - For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.
你有 k
个升序排列的整数数组。找到一个最小区间,使得 k
个列表中的每个列表至少有一个数包含在其中。
我们定义如果 b-a < d-c
或者在 b-a == d-c
时 a < c
,则区间 [a,b] 比 [c,d] 小。
示例 1:
输入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] 输出: [20,24] 解释: 列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。 列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。 列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。
注意:
- 给定的列表可能包含重复元素,所以在这里升序表示 >= 。
- 1 <=
k
<= 3500 - -105 <=
元素的值
<= 105 - 对于使用Java的用户,请注意传入类型已修改为List<List<Integer>>。重置代码模板后可以看到这项改动。
344ms
1 class Solution { 2 func smallestRange(_ nums: [[Int]]) -> [Int] { 3 var point2Lists = [Int: [Int]]() 4 for i in 0..<nums.count { 5 for n in nums[i] { 6 point2Lists[n, default:[Int]()].append(i) 7 } 8 } 9 10 let kvs = point2Lists.sorted(by: {$0.0 < $1.0}) 11 let k = nums.count 12 var counter = Array(repeating: 0, count: k) 13 var ret = [0, Int.max] 14 var coveredLists = 0 15 var i = 0 16 for e in 0..<kvs.count { 17 let (n, lists) = kvs[e] 18 for l in lists { 19 if counter[l] == 0 { 20 coveredLists += 1 21 } 22 counter[l] += 1 23 } 24 25 while coveredLists == k { 26 let (m, lists) = kvs[i] 27 if ret[1] - ret[0] > n - m { 28 ret = [m, n] 29 } 30 for l in lists { 31 if counter[l] == 1 { 32 coveredLists -= 1 33 } 34 counter[l] -= 1 35 } 36 i += 1 37 } 38 } 39 40 return ret 41 } 42 }
Runtime: 432 ms
Memory Usage: 21.8 MB
1 class Solution { 2 func smallestRange(_ nums: [[Int]]) -> [Int] { 3 var nums = nums 4 var res:[Int] = [Int]() 5 var v:[[Int]] = [[Int]]() 6 var m:[Int:Int] = [Int:Int]() 7 for i in 0..<nums.count 8 { 9 for num in nums[i] 10 { 11 v.append([num, i]) 12 } 13 } 14 v.sort(by:{(a:[Int],b:[Int]) -> Bool in 15 if a[0] == b[0] 16 { 17 return a[1] < b[1] 18 } 19 else 20 { 21 return a[0] <= b[0] 22 } 23 }) 24 var left:Int = 0 25 var n:Int = v.count 26 var k:Int = nums.count 27 var cnt:Int = 0 28 var diff:Int = Int.max 29 for right in 0..<n 30 { 31 if m[v[right][1],default:0] == 0 32 { 33 cnt += 1 34 } 35 m[v[right][1],default:0] += 1 36 while(cnt == k && left <= right) 37 { 38 if diff > v[right][0] - v[left][0] 39 { 40 diff = v[right][0] - v[left][0] 41 res = [v[left][0], v[right][0]] 42 } 43 44 m[v[left][1],default:0] -= 1 45 if m[v[left][1]] == 0 46 { 47 cnt -= 1 48 } 49 left += 1 50 } 51 } 52 return res 53 } 54 }
768ms
1 /* Solution Space */ 2 3 class Solution 4 { 5 6 func smallestRange( _ nums: [ [ Int ] ] ) -> [ Int ] 7 { 8 9 var traversalsHeap: BinaryHeap< ArrayTraversal > = BinaryHeap< ArrayTraversal >( 10 { 11 return ( $0.currentValue <= $1.currentValue ) 12 } 13 ) 14 15 var currentMax: Int = Int.min 16 17 for array in nums 18 { 19 if array.count > 0 20 { 21 22 let newTraversal: ArrayTraversal = ArrayTraversal( array ) 23 24 traversalsHeap.insertElement( newTraversal ) 25 26 currentMax = max( currentMax, newTraversal.currentValue ) 27 28 } 29 } 30 31 guard traversalsHeap.getSize() > 0 32 else 33 { 34 return [] 35 } 36 37 var minSize: Int = Int.max 38 39 var minStart: Int = -1 40 var minEnd: Int = -1 41 42 while true 43 { 44 45 let minTraversal: ArrayTraversal = traversalsHeap.deleteTopElement()! 46 47 let currentMin: Int = minTraversal.currentValue 48 let currentSize: Int = ( currentMax - currentMin ) 49 50 if currentSize < minSize 51 { 52 53 minSize = currentSize 54 55 minStart = currentMin 56 minEnd = currentMax 57 58 } 59 60 if minTraversal.getNextValue() 61 { 62 63 currentMax = max( currentMax, minTraversal.currentValue ) 64 65 traversalsHeap.insertElement( minTraversal ) 66 67 } 68 else 69 { 70 break 71 } 72 } 73 return [ minStart, minEnd ] 74 75 } 76 } 77 78 /* Binary Heap Type */ 79 80 open class BinaryHeap< Type > 81 { 82 83 /* Heap Array */ 84 private var heapArray: [ Type ] 85 86 /* In Order Function */ 87 private let inOrder: ( _ a: Type, _ b: Type ) -> Bool 88 89 /* Initializer */ 90 91 public init( _ inOrder: @escaping ( _ a: Type, _ b: Type ) -> Bool ) 92 { 93 94 self.heapArray = [ Type ]() 95 96 self.inOrder = inOrder 97 98 } 99 100 /* Get Size */ 101 102 open func getSize() -> Int 103 { 104 105 return ( heapArray.count ) 106 107 } 108 109 /* Get Tale */ 110 111 private func getTale() -> Int 112 { 113 114 return ( heapArray.count - 1 ) 115 116 } 117 118 /* Get Parent */ 119 120 private func getParent( _ nodePosition: Int ) -> Int? 121 { 122 123 if nodePosition <= 0 124 { 125 return nil 126 } 127 128 let parentPosition: Int = ( ( nodePosition - 1 ) / 2 ) 129 130 return parentPosition 131 132 } 133 134 /* Get Left Child */ 135 136 private func getLeftChild( _ nodePosition: Int ) -> Int? 137 { 138 139 let childPosition = ( nodePosition * 2 ) + 1 140 141 if childPosition <= getTale() 142 { 143 return childPosition 144 } 145 else 146 { 147 return nil 148 } 149 150 } 151 152 /* Get Right Child */ 153 154 private func getRightChild( _ nodePosition: Int ) -> Int? 155 { 156 157 let childPosition = ( nodePosition * 2 ) + 2 158 159 if childPosition <= getTale() 160 { 161 return childPosition 162 } 163 else 164 { 165 return nil 166 } 167 168 } 169 170 /* Insert Element */ 171 172 open func insertElement( _ element: Type ) 173 { 174 175 heapArray.append( element ) 176 177 var traversal1 = getTale() 178 var goingUp = true 179 180 while goingUp 181 { 182 183 if let parent = getParent( traversal1 ) 184 { 185 186 if( !inOrder( heapArray[ parent ], heapArray[ traversal1 ] ) ) 187 { 188 189 let temp = heapArray[ traversal1 ] 190 heapArray[ traversal1 ] = heapArray[ parent ] 191 heapArray[ parent ] = temp 192 193 traversal1 = parent 194 195 } 196 else 197 { 198 goingUp = false 199 } 200 201 } 202 else 203 { 204 goingUp = false 205 } 206 207 } 208 209 } 210 211 /* Get Top Element */ 212 213 open func getTopElement() -> Type? 214 { 215 216 if getSize() == 0 217 { 218 return nil 219 } 220 else 221 { 222 return heapArray[ 0 ] 223 } 224 225 } 226 227 /* Delete Top Element */ 228 229 open func deleteTopElement() -> Type? 230 { 231 232 if getSize() == 0 233 { 234 return nil 235 } 236 237 let value = getTopElement() 238 239 heapArray[ 0 ] = heapArray[ getTale() ] 240 heapArray.removeLast() 241 242 if( getSize() > 1 ) 243 { 244 245 var traversal = 0 246 var goingDown = true 247 248 while( goingDown ) 249 { 250 251 var topChild: Int? = nil 252 253 if let child = getLeftChild( traversal ) 254 { 255 256 topChild = child 257 258 } 259 260 if let child = getRightChild( traversal ) 261 { 262 263 if( topChild == nil || !inOrder( heapArray[ topChild! ], heapArray[ child ] ) ) 264 { 265 266 topChild = child 267 268 } 269 270 } 271 272 if( topChild != nil && !inOrder( heapArray[ traversal ], heapArray[ topChild! ] ) ) 273 { 274 275 let temp = heapArray[ traversal ] 276 heapArray[ traversal ] = heapArray[ topChild! ] 277 heapArray[ topChild! ] = temp 278 279 traversal = topChild! 280 281 } 282 else 283 { 284 goingDown = false 285 } 286 287 } 288 289 } 290 291 return value 292 293 } 294 295 } 296 297 /* Array Traversal Type */ 298 299 class ArrayTraversal 300 { 301 302 private let array: [ Int ] 303 private var currentIndex: Int 304 305 private(set) var currentValue: Int 306 307 init( _ array: [ Int ] ) 308 { 309 310 self.array = array 311 self.currentIndex = 0 312 313 self.currentValue = array[ currentIndex ] 314 315 } 316 317 func getNextValue() -> Bool 318 { 319 320 if currentIndex == ( array.count - 1 ) 321 { 322 return false 323 } 324 325 currentIndex += 1 326 327 currentValue = array[ currentIndex ] 328 329 return true 330 331 } 332 333 }
1392ms
1 class Solution { 2 func smallestRange(_ nums: [[Int]]) -> [Int] { 3 var res = Array.init(repeating: 0, count: 2) 4 5 var m = [Int:Int]() 6 var items = [[Int]]() 7 var cnt = 0 8 for i in 0..<nums.count { 9 for n in nums[i] { 10 items.append([n, i]) 11 } 12 } 13 14 items.sort(by: {$0.first! < $1.first!}) 15 16 var left = 0, right = 0 17 var diff = Int.max 18 while right < items.count { 19 if m[items[right].last!] == nil || m[items[right].last!] == 0 { 20 cnt += 1 21 m[items[right].last!] = 0 22 } 23 24 m[items[right].last!] = m[items[right].last!]! + 1 25 26 while cnt == nums.count && left <= right { 27 if diff > items[right].first! - items[left].first! { 28 diff = items[right].first! - items[left].first! 29 res = [items[left].first!, items[right].first!] 30 } 31 32 m[items[left].last!] = m[items[left].last!]! - 1 33 if (m[items[left].last!] == 0) {cnt -= 1} 34 left += 1 35 } 36 37 right += 1 38 } 39 40 return res 41 } 42 }
7412ms
1 class Solution { 2 func smallestRange(_ nums: [[Int]]) -> [Int] { 3 var pointers = Array(repeating: 0, count: nums.count) 4 var minDiff = Int.max 5 var output = [Int.min, Int.max] 6 while true { 7 var minIndex = 0 8 var maxValue = Int.min 9 var minValue = Int.max 10 for i in 0 ..< pointers.count { 11 let value = nums[i][pointers[i]] 12 maxValue = max(maxValue, value) 13 if value < minValue { 14 minIndex = i 15 minValue = value 16 } 17 } 18 let diff = maxValue - minValue 19 if diff < minDiff { 20 minDiff = diff 21 output[0] = minValue 22 output[1] = maxValue 23 } 24 pointers[minIndex] += 1 25 if pointers[minIndex] > nums[minIndex].count - 1 { 26 return output 27 } 28 } 29 return [] 30 } 31 }