2-sum 和 3-sum 問題的快速解法

用科學方法分析程序中介紹了 3-sum 問題的暴力解法(ThreeSum)——用三個嵌套的 for 循環來求和爲 0 的三元組個數,增長數量級爲立方級別。

類似地,對於 2-sum 問題(找出一個輸入中所有和爲 0 的整數對的數量),可用兩個嵌套的 for 循環來解決(TwoSum),增長數量級爲平方級別。

將輸入數據排序後應用二分查找,可得到 2-sum 的快速解法(假設輸入的所有整數均各不相同):

首先將數組排序(爲二分查找做準備),然後對於數組中的每個 a[i],使用 BinarySearch 的 rank() 方法對 -a[i] 進行二分查找。如果結果爲 j 且 j>i[1],我們就將計數器加 1。

歸併排序所需的時間和 NlogN 成正比,二分查找所需的時間和 logN 成正比,因此整個算法的運行時間和 NlogN 成正比。

2-sum 問題的線性對數級別的解法

和剛纔一樣,我們假設所有整數均各不相同。當且僅當 -(a[i] +a[j]) 在數組中時,整數對(a[i] 和 a[j])爲某個和爲 0 的三元組的一部分。下面代碼框中的代碼會將數組排序並進行 N(N-1)/2 次二分查找[2],每次查找所需的時間都和 logN 成正比。因此總運行時間和 N2logN 成正比。

3-sum 問題的 N2lgN 解法

圖 1 顯示了用這 4 種算法的成本的懸殊差距。

圖 1 解決 2-sum 和 3-sum 問題的各種算法的成本

下界

我們還能找到比 2-sum 問題的 TwoSumFast 和 3-sum 問題的 ThreeSumFast 快得多的算法嗎?是否存在解決 2-sum 問題的線性級別的算法,3-sum 問題的線性對數級別的算法?對於 2-sum,這個問題的回答是沒有(在僅允許在線性或是平方級別計算或比較這些整數的成本模型下);對於 3-sum,回答是不知道,不過專家們相信 3-sum 可能的最優算法是平方級別的。

爲算法在最壞情況下的運行時間給出一個下界的思想是非常有意義的,它非常有助於指引我們追求更加有效的算法。


  1. 這個條件測試覆蓋了三種情況:

    ❏ 如果二分查找不成功則會返回 -1,因此我們不會增加計數器的值;

    ❏ 如果二分查找返回的 j>i,我們就有 a[i] + a[j] = 0,增加計數器的值;

    ❏ 如果二分查找返回的 j 在 0 和 i 之間,我們也有 a[i] + a[j] = 0,但不能增加計數器的值,以避免重複計數。 ↩︎

  2. 兩個 for 循環的作用是選二元組,在 N 個數中選二元組有 C(2,N)=N!/[(N-2)!2!]=N(N-1)/2 種選法。 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章