658. Find K Closest Elements
題目網址:https://leetcode.cn/problems/find-k-closest-elements/
題意:給一已排序的 array
arr以及兩整數k和x, 從arr中找到最接近x的k個數。返回的 array 必須是已排序好的。整數
a比整數b更接近x須滿足:
|a - x| < |b - x|(a比b更靠近x) 或|a - x| == |b - x|且a < b(兩者到x的距離相等, 但a比b小)

Solution 1:
想法:由於
arr是有序的, 所以最後返回的k個元素也一定是有序的, 其實就是返回了原 array 中的一個長度為k的 subarray。實際上相當於在長度為n的 array 中去掉n - k個數字, 而且去掉的順序肯定是從兩頭開始, 因為距離x最遠的數字肯定在首尾出現。➔ 每次比較首尾兩個數字跟
x的距離, 並刪除距離較大的數字, 直到剩餘的 array 長度為 k 為止
class Solution { |
- time:$O(n-k)$ ➔ while loop, 其中
n為arr.size() - space:$O(1)$ ➔ 扣除要返回的 array, 只需常數空間
Solution 2:
想法:利用移動 window, 從位置
i開始延伸出去的長度為k的 window(其中0 ≤ i ≤ n-k)以下圖為例,
nums = [1,2,3,4,5], 其中每個不同顏色的框代表不同的 window
➔ 利用 Binary Search, 算出 mid 後, 先看最左邊元素為 mid 的 window, 然後其右邊一個的 window 進行比較
e.g. 圖中,
mid = 2, 故當前 window 為藍框的[3,4], 右邊一個的 window 為紫框的[4,5]透過比較
arr[mid]及右邊一個的 window 中最右的元素arr[mid + k]來決定要往哪繼續做 Binary Searche.g. 透過上例, 比較
3和5來決定要縮小左邊界 or 右邊界由於 5 比較接近
x = 5, 故往右走(右半邊剩下的 window 繼續做 Binray Search)
class Solution { |
- time:$O(log(n) + k)$
- $O(log(n))$:binary search
- $O(k)$:建立返回的 array
- space:$O(1)$ ➔ 扣除要返回的 array, 只需常數空間
