658. Find K Closest Elements 找到 K 个最接近的元素
作者: 负雪明烛 id: fuxuemingzhu 个人博客: https://fuxuemingzhu.cn/
题目地址: https://leetcode.com/problems/find-k-closest-elements/description/
Given a sorted array, two integers k and x, find the k closest 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:
- The value k is positive and will always be smaller than the length of the sorted array.
- Length of the given array is positive and will not exceed 104
- 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.
在数组arr中找出离x最近的k个数。
解法比较多。比较容易想到的一种解法是使用计算每个数字和x的距离,然后找出最近距离的数字。这就是常见的TopK问题。使用小根堆很容易实现。
时间复杂度是O(N),空间复杂度是O(N)。
class Solution(object): def findClosestElements(self, arr, k, x): """ :type arr: List[int] :type k: int :type x: int :rtype: List[int] """ N = len(arr) sub = [((arr[i] - x) ** 2, i) for i in range(N)] heapq.heapify(sub) return sorted([arr[heapq.heappop(sub)[1]] for i in range(k)])方法二:双指针
Section titled “方法二:双指针”由于数组已经排序,完全可以从左右两个方向向中间遍历,每次找到距离大的那个数字,弹出去就好了,最后保留k个数字。
class Solution(object): def findClosestElements(self, arr, k, x): """ :type arr: List[int] :type k: int :type x: int :rtype: List[int] """ while len(arr) > k: if x - arr[0] <= arr[-1] - x: arr.pop() else: arr.pop(0) return arr方法三:二分查找
Section titled “方法三:二分查找”最简单思想的二分是找出x的位置,然后找出其旁边的k个数。但是下面这个做法惊为天人,比较区间两端的数值和x的距离,如果左边离得远了,就向右边走;如果右边离得远了,就像左边走。这个对二分查找的理解必须很深刻了。
class Solution(object): def findClosestElements(self, arr, k, x): """ :type arr: List[int] :type k: int :type x: int :rtype: List[int] """ left = 0 right = len(arr) - 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]参考资料:
http://www.cnblogs.com/grandyang/p/7519466.html
2018 年 10 月 8 日 —— 终于开学了。

评论与交流