美文网首页
658. 找到k个最接近的数(Python)

658. 找到k个最接近的数(Python)

作者: 玖月晴 | 来源:发表于2020-11-24 20:21 被阅读0次

    题目

    难度:★★★☆☆
    类型:数学
    方法:数学

    力扣链接请移步本题传送门
    更多力扣中等题的解决方案请移步力扣中等题目录

    给定一个排序好的数组,两个整数 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]

    说明:

    k 的值为正数,且总是小于给定排序数组的长度。
    数组不为空,且长度不超过 104
    数组里的每个元素与 x 的绝对值不超过 104

    解答

    解法1:滑动窗口

    题目的要求是,在arr排序数组中,找到k个与x最接近的数字,并按顺序返回。

    我们准备一个长度为k的窗口,在arr数组上滑动的过程中,该窗口中的元素一定会存在某种情况,成为题目的答案,重要的是,如何控制窗口的停止滑动。

    窗口停止滑动时,应该满足的是,窗口最右端的元素与x的绝对值差值不大于窗口最左端的元素。

    class Solution:
        def findClosestElements(self, arr, k: int, x: int):
            heap = []
            for i in range(len(arr)):
                if len(heap) < k:
                    heap.append(arr[i])
                else:
                    if abs(arr[i] - x) < abs(heap[0] - x):
                        heap.pop(0)
                        heap.append(arr[i])
            return heap
    

    解法2:二分法

    处理已经排序好的数组的最高效的方法是二分法。二分法有几个关键因素,即左右起始端点的确定,状态的更新以及返回的结果。我们这里使用二分法的目标是,找到中点mid,作为最终返回的窗口的左端位置。

    左右端点的确定:选取左端点位置为0,右端点位置为len(arr)-k,因为mid作为左端,一定不会超过这个值。

    状态更新:x - arr[mid] > arr[mid + k] - x时,左端点右移,否则右端点左移。

    class Solution:
        def findClosestElements(self, arr, k: int, x: int):
            size = len(arr)
            left = 0
            right = size - k
            while left < right:
                mid = left + (right - left) // 2
                if x - arr[mid] > arr[mid + k] - x:
                    left = mid + 1
                else:
                    right = mid
            return arr[left:left + k]
    

    如有疑问或建议,欢迎评论区留言~

    有关更多力扣中等题的python解决方案,请移步力扣中等题解析

    相关文章

      网友评论

          本文标题:658. 找到k个最接近的数(Python)

          本文链接:https://www.haomeiwen.com/subject/cmswiktx.html