《程式設計之美》 尋找最近點對

2021-07-07 10:29:37 字數 2242 閱讀 6689

問題:

給定平面上兩個點的座標,找出距離最近的兩個點。

分析與解法:

一般思路是蠻力演算法,兩兩求n個點之間的距離並比較,得出最大距離,時間複雜度為o(n^2)

優化演算法是採用分治的思想,將n個點先按照 x 軸的座標的中值 x = mx 平均分為左右兩組,分別求出 xl 和 xr 中的最近點對的距離,因為最近點對一定是出現 xl 或 xr 中,或者是xl中的乙個點與 xr 中的乙個點之間,所有再將左右最近點對間的距離進行比較,取較小值 mdist,在帶狀區域 x=mx-mdist 和x=mx+mdist 之間以 y 軸座標進行歸併排序,如果乙個點對的距離小於mdist,那麼它們一定在乙個mdist*(mdist+mdist) 的區域中

根據理論,可以用o(n)的時間複雜度完成帶狀區域中最近點對的查詢,總的時間複雜度是o(nlogn)

擴充套件問題:

1.找出一維陣列中相鄰兩個數的最大差值。

2.找出平面上距離最遠的兩個點之間的距離。

分析與解法:

1.一般思路是使用排序演算法將陣列轉化為有序陣列時間複雜度為o(nlogn),在通過一次遍歷陣列得到相鄰兩個數的最大差值,時間複雜度為o(n),總的時間複雜度為o(nlogn)

為了提高時間複雜度可以使用空間換時間的方法,使用桶排序求解,其時間複雜度和空間複雜度都為o(n)

(1) 掃面一遍陣列,找到陣列中的最大值max,最小值min。時間複雜度o(2*n)。

(2) 將[min, max]區間分為n-1個區間段(每個區間段對應乙個桶bucket)。

(3) 再次從頭到尾掃瞄陣列,將每個元素新增到相應的桶bucket裡面。 注意:有的桶為空(不含任何資料),可以使用兩個變數記錄下桶中的最小值first和最大值second。時間複雜度o(2*n)。

(4) 然後按順序將每個( 非空 )的相鄰的桶進行比較。桶內元素之間的差值肯定不是最大差值,故不需要計算,最大差值只可能是前乙個桶的最大值與後乙個桶中的最小值之間的差值。最後選擇最大的非空相鄰桶的距離返回即可。時間複雜度o(n)。

**:

#include 

#include

#include

using

namespace

std;

/**乙個無序的實數陣列,求它們最近鄰的兩個值的最大差值**/

double maxdiff(double a, int n)

if (min > a[i])

}double bar = (max - min)/(n-1);

int pos; //pair: first表示桶中最小元素的index,second表示桶中最大元素的index

vector

< pair > buckets(n,make_pair(-1,-1));

//這裡桶記憶體相應資料的下標,而不是相應的資料,方便後面的資料計算,以免有精度損失。

for (int i=0; iint)((a[i] - min)/bar);

if ((buckets[pos].first == -1) && (buckets[pos].second == -1))

else

} int lastix=0;

double max_diff = 0;

double tmp_diff = 0;

for (int i=1; i//計算桶之間的距離

if ((buckets[i].first == -1) && (buckets[i].second == -1))

else

lastix = i;

//lastix指上乙個非空桶的index,且第乙個桶和最後乙個桶肯定非空。

} }

return max_diff;

} int main()

; cout

<8)

0; }

2.對於平面上有n個點,這一對最遠點必然存在於這n個點所構成的乙個凸包上。然後使用凸包演算法求解。

文章及**參考以下博文:

程式設計之美2 11 尋找最近的點對

求點集中的最近點對有以下兩種方法 設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。解體思路 1 蠻力法 適用於點的數目比較小的情況下 1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n...

尋找最近點對

一維的數很簡單,先排序,再掃瞄已排好的數,相鄰兩個進行比較即可,時間複雜度為o n log2n n o n log2n 兩維的話 把平面上n個點分成兩部分left和right。假設分別求出left和right兩部分最短距離mindistleft和mindistright,還有一種情況就是點對中乙個點...

尋找最近點對

問題 在空間中有n個點,尋找空間中最近的2個點。法一 遍歷,o n 2 法二 分治演算法 將點分為左右兩半,分別找到最近的2個點,然後考慮交叉位置的點對中的最小距離,在這3者中取最小的那個。o nlogn 步驟 1.按照x軸排序 2.找到中間點,分別進行處理 3.2邊處理完成,將進行 merge 過...