輸入資料樣本很少
直接排序
def
kclosest
(self, points: list[list[
int]
], k:
int)
-> list[list[
int]]:
dis =
for i,point in
enumerate
(points)
:[i,point[0]
**2+point[1]
**2])
mdis =
sorted
(dis,key =
lambda x:x[1]
)[:k] ans =
for i in mdis:0]
])return ans
通過了
時間複雜度o(n
logn
)o(nlogn)
o(nlog
n)空間複雜度o(n
)o(n)
o(n)
方法一
使用堆排取到前k個距離最小的元素
import heapq as hq
class
solution
:def
kclosest
(self, points: list[list[
int]
], k:
int)
-> list[list[
int]]:
heap =
mdis = hq.nsmallest(k,points,
lambda x:x[0]
**2+x[1]**
2)return mdis
時間複雜度o(n
logn
)o(nlogn)
o(nlog
n)空間複雜度o(n
)o(n)
o(n)
方法二
構造小根堆,然後遍歷所有點來構建堆,最後的堆就是結果
class
solution
:def
kclosest
(self, points: list[list[
int]
], k:
int)
-> list[list[
int]]:
hq =[(
-x**
2-y**
2,i)
for i,
(x,y)
inenumerate
(points[
:k])
] heapq.heapify(hq)
for i in
range
(k,len
(points)):
x,y = points[i]
dis =
-x**
2-y**
2if dis>hq[0]
[0]:
(dis,i)
) ans =
[points[i]
for(_, i)
in hq]
return ans
需要注意的是我們要儲存平方和的相反數,用來表示最小的距離,python裡面預設是小根堆
假設我們現在構造的是大根堆,則堆頂元素始終是最大的
因為我們要取得前k個最小的數,所以我們先用前k個元素構造乙個大根堆,用它們的平方和來表示距離,然後比較堆頂元素和剩下的點,如果當前點的距離小於堆頂,即當前元素小於堆中最大的元素,那麼用當前元素來替換堆頂,即pop再push
python裡面預設是小根堆,我們只需要儲存負的平方和就能達到效果
時間複雜度o(n
logk
)o(nlogk)
o(nlog
k)空間複雜度o(k
)o(k)
o(k)
與堆排相比優化了時間、空間複雜度
快排每次排序確定乙個元素的最終位置,這個元素的左邊都小於它,這個元素的右邊都大於它
如果某次快排取得的元素
這樣的應用常見於按要求取得前k個數的題目,例如劍指offer 40.最小的k個數這篇文章介紹了快排的解法
還有很多相似的題目:
陣列中的第k個最大元素
347. 前 k 個高頻元素
這些前k個、第k個,都可以被分類為top-k問題
都是可以用快排解決的問題
對於此題,我們先寫乙個簡單的快排,排序乙個元素到它最終的位置,那麼最終位置i和k之間的關係一共有三種情況
i==k,返回[:k]個元素
i>k,在[left:i]之間繼續快排
i
class
solution
:def
kclosest
(self, points: list[list[
int]
], k:
int)
-> list[list[
int]]:
if k ==
len(points)
:return points
left,right =0,
len(points)-1
pos = self.randompick(points,left,right)
while pos!=k:
if pos>k:
pos = self.randompick(points,left,pos-1)
elif pos
pos = self.randompick(points,pos+
1,right)
# print(points)
return points[
:k]def
randompick
(self,lst,left,right)
:# pivot = random.randint(left,right)
# lst[left],lst[pivot] = lst[pivot],lst[left]
pivot_val = lst[left]
i,j=left,right
pdis = lst[left][0
]**2+lst[left][1
]**2while i
while i
]**2+lst[j][1
]**2>= pdis:
j-=1 lst[i]
= lst[j]
while i
]**2+lst[i][1
]**2<= pdis:
i+=1 lst[j]
= lst[i]
lst[i]
= pivot_val
return i
這個快排在資料很多的時候超時了,可見必須要改進,先寫到這裡 973 最接近原點的 K 個點
我們有乙個由平面上的點組成的列表points。需要從中找出k個距離原點 0,0 最近的點。這裡,平面上兩點之間的距離是歐幾里德距離。你可以按任何順序返回答案。除了點座標的順序之外,答案確保是唯一的。示例 1 輸入 points 1,3 2,2 k 1 輸出 2,2 解釋 1,3 和原點之間的距離為 ...
leetcode 973 最接近原點的 K 個點
我們有乙個由平面上的點組成的列表 points。需要從中找出 k 個距離原點 0,0 最近的點。這裡,平面上兩點之間的距離是歐幾里德距離。你可以按任何順序返回答案。除了點座標的順序之外,答案確保是唯一的。示例 1 輸入 points 1,3 2,2 k 1 輸出 2,2 解釋 1,3 和原點之間的距...
leetcode973 最接近原點的 K 個點
使用sort函式,自定義排序型別 class solution return 排序函式sort 標頭檔案 include,第三個引數可自定義的比較函式指標預設公升序 bool cmp const type1 a,const type2 b 比較a和b,如果想要公升序則讓 a b,返回true 如果想...