目錄
題目:在乙個 n≥首先很容易想到暴力破解的方法,但是需要 o(n22 個點的集合 q 中尋找距離最近的點對
) 的時間複雜度,所以考慮使用分治法,但將複雜度降為 o(nlogn) 還需要一些優化。 (關於執行時間的遞迴式為 t(n) = 2t(n2
) + o(n))。
思路:把點集分為兩半,最近點對可能全部屬於左半點集,或者右半點集,或者乙個屬於左半點集,乙個屬於右半點集。所以最終結果為這三種情況的最小值。
分治法一般分為三個步驟:
「分解」 和 「解決」 部分很好實現,重點在於如何實現合併。
首先我們不能把左半部分點集中的點挨個與右半部分的所有點算距離,這樣總體來看跟暴力破解就沒什麼區別了,所以需要優化,減少需要計算距離的點對個數。優化的辦法是:
到目前為止,演算法的時間複雜度的遞迴式是 t(n) = 2t(n2
) + o(n) + o(nlogn), 要達到目標是 t(n) = 2t(n2
) + o(n),還需優化排序帶來的 o(nlogn)。
《演算法導論》中給出的是方法是「預排序」:在第一次遞迴呼叫前,就把點集 p 分別按照橫座標和縱座標排好序得到陣列 x 和陣列 y,然後在傳進函式。不用再遞迴函式內部進行排序操作。所以總算法複雜度為 o(nlogn)。
但這樣就會有乙個問題,每次遞迴前,會將陣列 x 和陣列 y 折半劃分為 xl
、xr 和 yl
、yr 傳入函式,如何保證 xl
、yl (或者 xr
、yr
因為 yl
和 xl
中所有點的橫座標都小於 x 中間點的橫座標,必然屬於同一點集,且 yl
按照 y 排序的。
演算法導論 分治法 最近點對 HDOJ1007
hdoj1007的原題目是求出在不同時套中兩個玩具的前提下,圓圈的最大半徑。問題翻譯過來就是求解最近點對的問題,這個問題是經典的分治法問題。參考部落格 毫無疑問,通過暴力手段列舉所有的點對並計算這些點對的距離,找出最小的一組,可以得到最後的結果。但是,這道題的資料規模非常大,所以,這種傳統的方法肯定...
分治法求最近點對問題
分治法 1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數...
分治法求最近點對問題
1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數目乙個為...