【Leetcode解題】973. K Closest Points to Origin
題目
- 題目連結
- 目標函式 :
kClosest(points, k)- Input :
points: List[List[int]]、k: int - Output :
List[List[int]]
- Input :
解題概念
- 題意 : 給定一陣列
points,其中points[i] = [x_i, y_i]表示 X-Y 平面上的一點- X-Y 平面上兩點之間的距離是歐幾里德距離 $(\sqrt{(x_1-x_2)^2}+\sqrt{(y_1-y_2)^2})$
- 需要回傳離原點
(0, 0)最近的k個點 (以任意順序皆可)
我的寫法
- 想法 : 主要使用 Bubble Sort
- 在比較的過程中,使用
distance()去比較兩者的值(即歐幾里德距離) - 以距離近到遠排序
- 最後回傳
points[:k]
- 在比較的過程中,使用
- 程式碼 :
1
2
3
4
5
6
7
8
9
10
11
12
13def kClosest(self, points, k):
def distance(point):
return math.sqrt(point[0] ** 2 + point[1] ** 2)
for i in range(len(points)):
for j in range(i+1, len(points)):
if distance(points[i]) > distance(points[j]):
temp = points[i]
points[i] = points[j]
points[j] = temp
return points[:k] - 成效 :
- Time Complexity : Time Limit Exceeded
解答 or 其他優秀寫法 - Part1
- 想法 : 使用 Max Heap 去整理
points,在中間比較的時候使用歐幾里德距離去比較 - 實作方法 : 直接使用
heapq套件,使用其中的nsmallest(n, iterable, key=None)方法 (回傳一個包含資料iterable中前n小元素的 list),其中包含以下參數 :n = k: 要回傳前k小元素iterable = points: 對資料points進行比較key = lambda (x, y): x * x + y * y: 為比較的依據,這裡使用lambda計算歐幾里德距離去比較
- 程式碼 :
1
2
3
4
5import heapq
def kClosest(self, points, k):
return heapq.nsmallest(k, points, key = (lambda (x, y): x * x + y * y)) - 成效 :
- Time Complexity : $O(n)$
- Runtime: 569 ms (faster than 82.41%)
- Memory Usage: 19.7 MB (more than 74.58%)
解答 or 其他優秀寫法 - Part2
- 想法 : 一樣使用 Max Heap 去整理
points,在中間比較的時候使用歐幾里德距離去比較 - 實作方法 : 這次改使用手動的方式去操作 Max Heap
- Heap 內儲存的格式為
(dist, x, y)dist: 為歐幾里德距離,特別的是這裡使用dist = -(x * x + y * y)的方式去儲存,進而可以讓 Max Heap 儲存前k小的元素
- 建立一個空間為
k的 Heap,並依序去判斷points的各元素- 若插入一元素時發現 Heap 已滿 : 則使用
heapq.heappushpop(heap, (dist, x, y))(元素放入後執行 Delete-MAX) - 若插入一元素時發現 Heap 未滿 : 則使用
heapq.heappush(heap, (dist, x, y))(元素直接插入到 Heap 中)
- 若插入一元素時發現 Heap 已滿 : 則使用
- 最後將
heap整理成所需格式並回傳
- Heap 內儲存的格式為
- 程式碼 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14import heapq
def kClosest(self, points, k):
heap = []
for (x, y) in points:
dist = -(x*x + y*y)
if len(heap) == k:
heapq.heappushpop(heap, (dist, x, y))
else:
heapq.heappush(heap, (dist, x, y))
return [(x,y) for (dist,x, y) in heap] - 成效 :
- Time Complexity : $O(n\log n)$
- Runtime: 574 ms (faster than 79.84%)
- Memory Usage: 20.1 MB (more than 55.33%)
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Robin's Tech Blog!


