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 }
  • 相关阅读:
    OnContextMenu事件
    一个不错的js制作的右键菜单
    用JS访问iframe中的元素
    Java中static、final用法小结
    Android系统层次结构及分析
    final 与static final修饰变量区别
    Jquery取得iframe中元素的几种方法Javascript Jquery获取Iframe的元素、内容或者ID,反之也行!
    js+css实现页面右键菜单
    编码和字符集的关系
    关于互联网开放的一点看法
  • 原文地址:https://www.cnblogs.com/strengthen/p/10485967.html
Copyright © 2011-2022 走看看