zoukankan      html  css  js  c++  java
  • [Swift]LeetCode658. 找到 K 个最接近的元素 | Find K Closest Elements

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10485967.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.

    Example 1:

    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.


    给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。

    示例 1:

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

    示例 2:

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

    说明:

    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 }
  • 相关阅读:
    zip压缩类
    sqlserver配置允许快照隔离
    (三)装饰模式
    (二)策略模式
    (一)简单工厂模式
    MFC中lib和dll的区别
    VC MFC工具栏(CToolBar)控件(非常重要)
    CMFCMenuBar和CMFCToolBar相同ID,在显示不同标签文字
    CImageList类Create函数参数解析
    c++连接数据库代码
  • 原文地址:https://www.cnblogs.com/strengthen/p/10485967.html
Copyright © 2011-2022 走看看