题意
给一个目标数 target, 一个非负整数 k, 一个按照升序排列的数组 A。在A中找与target最接近的k个整数。返回这k个数并按照与target的接近程度从小到大排序,如果接近程度相当,那么小的数排在前面。
注意事项
The value k is a non-negative integer and will always be smaller than the length of the sorted array.
Length of the given array is positive and will not exceed 10^4
Absolute value of elements in the array and x will not exceed 10^4
样例
如果 A = [1, 2, 3], target = 2 and k = 3, 那么返回 [2, 1, 3].
如果 A = [1, 4, 6, 8], target = 3 and k = 3, 那么返回 [4, 1, 6].
思路
这道题的一般解法都很容易想出来,暴力出奇迹嘛,这里我们只说最优解,也就是 O(logn + k) 的时间复杂度 的解法。
这道题的解题关键是数组A是有序的,只要有序就可以考虑用二分。
我们通过对A进行二分,找到最接近target的数,找到之后用双指针的思想,依次从找到的那个数向两边扩散,直到满足k个数为止。
思路较为简单,编码过程注意一些边界条件的判断即可。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 
 | class Solution:"""
 @param A: an integer array
 @param target: An integer
 @param k: An integer
 @return: an integer array
 """
 def kClosestNumbers(self, A, target, k):
 if k == 0:
 return []
 if not A:
 return []
 lp = None
 rp = None
 start = 0
 end = len(A) - 1
 while start + 1 < end:
 mid = int(start + (end - start) / 2)
 if A[mid] == target:
 start = mid
 end = mid + 1
 break
 elif A[mid] < target:
 start = mid
 else:
 end = mid
 if abs(A[start] - target) <= abs(A[start] - target):
 lp = start
 rp = end
 else:
 lp = end
 rp = end + 1
 cnt = 0
 ans = list()
 while cnt < k:
 cnt += 1
 if lp < 0 and rp >= len(A):
 return []
 elif lp < 0:
 ans.append(A[rp])
 rp += 1
 elif rp >= len(A):
 ans.append(A[lp])
 lp -= 1
 elif abs(A[lp] - target) <= abs(A[rp] - target):
 ans.append(A[lp])
 lp -= 1
 else:
 ans.append(A[rp])
 rp += 1
 return ans
 
 |