最近在工作中碰到了這個問題:已知在平面坐標系內有N個點,求離開給定坐標距離最近的10個點。
團隊的第一反應自然是按照兩點間距離公式, 遍歷N個已知點,然后排序獲得前10個最短距離的結果。
只是,我從來不是一個規規矩矩的人。我一直推崇用人類直覺思維來編程,而不要被僵化的程序思想束縛。
傳統距離公式,計算N個點的距離需要2N次的減法和平方。
而事實上, 一個真正的人類,是不會把所有N個點的距離都計算一遍的。大多數點都會被某些快速條件過濾掉的。
今天先把問題在這里寫下來, 有時間在把優化后的算法補充進來。
最差勁模式:
每次遍歷已知點數組,逐個計算兩點間距離,保留最小值以及索引信息。
時間復雜度 O(n)
缺點:每次查詢都要重新遍歷數組,效率低下。
優化模式1:
dic3提出的方式
預處理階段,遍歷所有已知點,得出一個初始化半徑,以確保至少能有一個或多個點在半徑內。
實際處理階段:
用初始化半徑,判斷半徑內的已知點。然后根據結果再次擴大或縮小半徑。
缺點:嚴重的問題是,如何知道半徑內的點都是誰?其實又要遍歷所有點了。
優化模式2:網格預處理
預處理階段,按已知坐標將所有點分配到二維數組內
實際處理階段:
按目標坐標計算並獲取核心下標,獲得二維數組內的一個元素
判斷這個網格內的所有點的距離並獲取結果。
如果目標點在網格邊緣,需要進一步增加相鄰網格內的數據來判斷。
缺點:
1、最差情況下要判斷4個網格
2、當網格內元素數量持續增加時,算法效率同樣下降明顯。
時間復雜度 O(n/網格數量)