[Swift]LeetCode658. 找到 K 個最接近的元素 | Find K Closest Elements

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-hkymqbjk-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Given a sorted array, two integers k and x, find the kclosest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.git

Example 1:github

Input: [1,2,3,4,5], k=4, x=3
Output: [1,2,3,4] 

Example 2:數組

Input: [1,2,3,4,5], k=4, x=-1
Output: [1,2,3,4] 

Note:微信

  1. The value k is positive and will always be smaller than the length of the sorted array.
  2. Length of the given array is positive and will not exceed 104
  3. Absolute value of elements in the array and x will not exceed 104

UPDATE (2017/9/19):
The arr parameter had been changed to an array of integers(instead of a list of integers). Please reload the code definition to get the latest changes.app


給定一個排序好的數組,兩個整數 k 和 x,從數組中找到最靠近 x(兩數之差最小)的 k 個數。返回的結果必需要是按升序排好的。若是有兩個數與 x 的差值同樣,優先選擇數值較小的那個數。spa

示例 1:code

輸入: [1,2,3,4,5], k=4, x=3
輸出: [1,2,3,4] 

示例 2:htm

輸入: [1,2,3,4,5], k=4, x=-1
輸出: [1,2,3,4] 

說明:blog

  1. k 的值爲正數,且老是小於給定排序數組的長度。
  2. 數組不爲空,且長度不超過 104
  3. 數組裏的每一個元素與 x 的絕對值不超過 104 

更新(2017/9/19):
這個參數 arr 已經被改變爲一個整數數組(而不是整數列表)。 請從新加載代碼定義以獲取最新更改。


Runtime: 328 ms
Memory Usage: 19.8 MB
 1 class Solution {
 2     func findClosestElements(_ arr: [Int], _ k: Int, _ x: Int) -> [Int] {
 3         var left:Int = 0
 4         var right:Int = arr.count - k
 5         while(left < right)
 6         {
 7             var mid:Int = left + (right - left) / 2
 8             if x - arr[mid] > arr[mid + k] - x
 9             {
10                 left = mid + 1
11             }
12             else
13             {
14                 right = mid
15             }
16         }
17         return Array(arr[left..<(left + k)])
18     }
19 }

336ms

 1 class Solution {
 2     func findClosestElements(_ arr: [Int], _ k: Int, _ x: Int) -> [Int] {
 3         if arr.count < 2 {
 4             return arr
 5         }
 6         
 7         let count = arr.count
 8         var closest = 0
 9         var minDiff = Int.max
10         var left = 0
11         var right = 0
12         var result = [Int]()
13         
14         for i in 0..<count {
15             let diff = abs(arr[i] - x)
16             if diff < minDiff || arr[i] == x {
17                 closest = i
18                 minDiff = diff
19             }
20         }
21         
22         left = closest
23         right = closest
24         while right - left + 1 < k {
25             if left - 1 < 0 {
26                 right += 1
27             } else if right + 1 > (count - 1) {
28                 left -= 1
29             } else if abs(x - arr[left - 1]) <= abs(x - arr[right + 1]) {
30                 left -= 1
31             } else {
32                 right += 1
33             }
34         }
35         
36         for i in left...right {
37             result.append(arr[i])
38         }
39         
40         return result
41     }
42 }

372ms

 1 struct Span {
 2     var start: Int
 3     var end: Int
 4     var mid: Int {
 5         return start + ((end - start) / 2)
 6     }
 7     var inverted: Bool {
 8         return end < start
 9     }
10     func leftRange() -> Span {
11         return Span(start: start, end: mid - 1)
12     }
13     func rightRange() -> Span {
14         return Span(start: mid + 1, end: end)
15     }
16 }
17 
18 
19 class Solution {
20     func findClosestIndex(arr: [Int], x: Int, span: Span) -> Int {
21         let mid = span.mid
22         
23         if mid == arr.count - 1 { return mid }
24         if mid <= 0 { return 0 }
25         
26         let midVal = arr[mid]
27         let nextVal = arr[mid + 1]
28         if midVal <= x && nextVal >= x {
29             return abs(x - midVal) <= abs(x - nextVal) ? mid : mid + 1
30         } else if midVal < x {
31             return findClosestIndex(arr: arr, x: x, span: span.rightRange())
32         } else {
33             return findClosestIndex(arr: arr, x: x, span: span.leftRange())
34         }
35     }
36     
37     func findClosestElements(_ arr: [Int], _ k: Int, _ x: Int) -> [Int] {
38         let startSpan = Span(start: 0, end: arr.count - 1)
39         let index = findClosestIndex(arr: arr, x: x, span: startSpan)
40         var left = index - 1
41         var right = index + 1
42         var returnVals: [Int] = [arr[index]]
43         for _ in 1..<k {
44             let rightVal = right < arr.count ? arr[right] : 10000000
45             let leftVal = left >= 0 ? arr[left] : 100000000
46             if abs(x - leftVal) <= abs(x - rightVal) {
47                 returnVals.append(leftVal)
48                 left -= 1
49             } else {
50                 returnVals.append(rightVal)
51                 right += 1
52             }
53         }
54         return returnVals.sorted()
55     }
56 }

416ms

 1 class Solution {
 2     
 3     func findStartIndex(_ arr: [Int], _ x: Int) -> Int {
 4         var i = 0
 5         while i < arr.count && arr[i] <= x {
 6             i += 1
 7         }
 8         
 9         return i
10     }
11     
12     func findClosestElements(_ arr: [Int], _ k: Int, _ x: Int) -> [Int] {
13         
14         var closest:[Int] = []
15         let startIndex = findStartIndex(arr, x)
16         var leftRunner:Int = startIndex - 1
17         var rightRunner:Int = startIndex
18         
19         while closest.count < k && (leftRunner >= 0 || rightRunner < arr.count) {           
20              
21             if leftRunner < 0 {
22                 closest.append(arr[rightRunner])
23                 rightRunner += 1
24                 continue
25             } else if rightRunner >= arr.count {
26                 closest.insert(arr[leftRunner], at: 0)
27                 leftRunner -= 1
28                 continue
29             }
30             
31             let left = arr[leftRunner]
32             let right = arr[rightRunner]
33             
34             if abs(x-left) <= abs(x-right) {
35                 closest.insert(left, at: 0)
36                 leftRunner -= 1
37             } else {
38                 closest.append(right)
39                 rightRunner += 1
40             }
41         }
42         
43         return closest
44     }
45 }

436ms

 1 class Solution {
 2     func findClosestElements(_ arr: [Int], _ k: Int, _ x: Int) -> [Int] {
 3         var res = [Int]()
 4         if x <= arr.first! {
 5             return Array(arr[0..<k])
 6         }
 7         if x >= arr.last! {
 8             return Array(arr[(arr.count - k)...])
 9         }
10         let index = binarySearch(arr, x)
11         var left = index - 1
12         var right = index + 1
13         res.append(arr[index])
14         while res.count < k {
15             if left < 0 {
16                 while res.count != k {
17                     res.append(arr[right])
18                     right += 1
19                 }
20                 break
21             } else if right >= arr.count {
22                 while res.count != k {
23                     res.append(arr[left])
24                     left -= 1
25                 }
26                 break
27             } else {
28                 if (x - arr[left]) <= (arr[right] - x) {
29                     res.append(arr[left])
30                     left -= 1
31                 } else {
32                     res.append(arr[right])
33                     right += 1
34                 }
35             }
36         }
37         return res.sorted()
38     }
39     
40     private func binarySearch(_ arr: [Int], _ x: Int) -> Int {
41         var left = 0
42         var right = arr.count - 1
43         while left < right {
44             let mid = left + (right - left)/2
45             if arr[mid] == x {
46                 return mid
47             } else if arr[mid] > x {
48                 right = mid - 1
49             } else {
50                 left = mid + 1
51             }
52         }
53         return left
54     }
55 }
相關文章
相關標籤/搜索