973 最接近原點的 K 個點

2021-10-10 08:57:04 字數 3611 閱讀 9540

輸入資料樣本很少

直接排序

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 如果想...