Meet in the middle思想的一些應用

2021-07-05 22:15:43 字數 2818 閱讀 1839



meet in the middle(有時候也叫作split and merge)是一種用以獲取足夠高效解決方案的靈巧的思想。和分治思想非常類似,它將問題分割成兩個部分,然後試著合併這兩個子問題的結果。好處在於通過使用一點額外的空間,你可以解決兩倍規模的原來可以解決的問題。

4和問題(流行的面試問題)

給定乙個整數陣列a,問陣列中是否存在4個數,使得這4個數的和是0(同乙個元素可以被多次使用)。例如:陣列a = [2, 3, 1, 0, -4, -1],一種可能的方案是3 + 1 + 0 - 4 = 0 或 0 + 0 + 0 + 0 = 0。

樸素的演算法是判斷所有可能的4個數的組合,這種方案需要計算o(n^4)次。

乙個些微改進的演算法是暴力搜尋所有的可能的n^3個3個數的組合,並且用hash表來判斷-(a+b+c)是否在原始的陣列中。這個演算法的複雜度是o(n^3) 

到目前為止,你可能想知道meet in the middle在這裡要怎麼應用,最關鍵的洞察來自於改寫a + b + c + d = 0 成 a + b = -(c + d)。現在我們可以儲存n^2個a+b的和在乙個hash表s中,然後可以列舉所有可能c和d的n^2種組合並且判斷s中是否包括-(c+d)。

**看起來這樣:

def 4sum(a):

sums = {}

for a in a:

for b in a:

sums[a + b] = (a, b)

for c in a:

for d in a:

if -(c + d) in sums:

print (sums[-(c + d)][0], sums[-(c + d)][1], c, d)

return

print "no solution."

這個演算法的時間複雜度和空間複雜度都是o(n^2),這個問題沒有已知的更快的演算法。

雙向搜尋

在乙個很大的圖中找到兩個點的最短路徑,比如說facebook的朋友關係圖(友誼圖)。

寬度優先搜尋演算法是這個問題的標準方法。假設這兩個節點之間之間的距離是k,並且網路中點的平均度數是p,那麼bfs演算法需要擴充套件o(p^k)個節點。

乙個更好的方案是同時從兩個節點開始搜尋,並且看什麼時候這兩個搜尋的邊界相遇。這個可以將需要擴充套件的節點降低到o(p^(k/2))。這個方案在尋路問題表現很好,包括明確的圖以及遊戲中遇到的不明確的圖。

破解2des加密

des是一種使用56bit金鑰的加密標準。今天計算機可以使用暴力搜尋的方法來破解加密。一種簡單的使得加密演算法更安全的方法是應用兩次加密,使用兩個不同的金鑰。這種方法容易受到diffile-hellman發明的中間者攻擊。3des工作的原理是通過用2個金鑰對明文進行3次加密。

我們來看看為什麼2des是容易受到攻擊的。假設ek是金鑰為k的加密函式,dk是金鑰為k的解密函式。2des演算法使用兩個金鑰k和k,ek(ek(p)) = s是乙個加密過程,並且dk(dk(s)) = p是乙個解密。

diffie-hellman的中間相遇攻擊用空間換取時間來找到這兩個金鑰。對於p,嘗試所有可能的金鑰可以取得對應的多個ek(p)的集合。同樣地,對於s可以用所有可能的金鑰來解密,取得所有可能dk(s)的集合。如果我們能夠在這兩個集合中找到匹配的一對,也就是說eki(p) = dkj(s),那麼金鑰就是ki和kj。

樸素的暴力演算法需要2^56*2^56次迭代來遍歷所有可能的k1和k2的值,而這個演算法使用2^56*56的空間來儲存所有的eki(p),並且2^56個操作來找到匹配。

這個是相當多的空間和相當多的計算時間。但對於乙個足夠大的公司或者國家,它就變得非常可能的範疇。

2001的國際奧賽的問題double要求破解24金鑰長度的2des就是非常可行的。

離散對數演算法

給定乙個素數n和p,q兩個數,0 <= p,q <= n-1,找到k使得p^k = q(mod n)。

樸素的演算法是遍歷所有可能的k的值,複雜度為o(n)。

baby-step, giant-step演算法使用了mitm,更高效地解決了這個問題。

記k = i[sqrt(n)] + j,i <= sqrt(n)且j <= sqrt(n)。替換等式中的k,我們有p^(i*[sqrt(n)] + j) = q(mod n),然後兩邊同除以p^j有:p^(i*sqrt(n)) = q*p^(-j) (mod n)

在這個時候,我們可以暴力搜尋等式兩邊並且找到乙個碰撞。

這個演算法需要o(sqrt(n))的空間和o(sqrt(n))的時間

警告

與分治不同,mitm不能用於遞迴,因為子問題和原問題沒有相同的結構。雙向搜尋在很多時候可以用其他的啟發式搜尋演算法來代替。

附加問題

1.朋友的朋友(面試問題)

給定社交網路中的兩個名字,設計乙個有效的方法,判斷其中乙個是否是另外乙個的朋友的朋友

2.6度空間(6度間隔/6度分割)

給定社交網路中的兩個名字,設計乙個有效的方法,判斷這兩個人是否最多相隔6個朋友

演算法的一些思想

目錄 0.總1.乘除法慢與加減法 2.窮舉演算法思想 3.遞推演算法思想 4.遞迴演算法思想 5.分治演算法思想 6.概率演算法思想 7.貪心演算法思想並不貪婪 追求最優求解,但不一定是能找到最優解 8.試探法演算法思想是一種委婉的做法 也叫回溯法 9.迭代演算法 輾轉法 10.動態規劃 五種基本演...

C 程式設計的一些思想

看完c primer後,了解了c 的語法,但我想往思想,設計方面深究,所以我選擇了看c 程式設計思想。以下是第一章中我記下的筆記。oop 物件導向的程式設計 重用乙個類最簡單的方法就是直接使用這個類的物件,並且還可以講這個類的物件放到乙個新類的裡面。可以用任何數量和型別的其他物件組成新類,通過組合得...

程式中的一些思想

看過mooc上的闞道巨集的c 課程,感覺講語法方面基本上是照本宣科,但是談到的幾個程式思維讓人眼前一亮。後續有新的感悟將不定期跟新。結合自己的理解,記錄如下 1.關於遞推 recursion 和遞迴 regression 兩者是相反的思維,recursion是已知問題n,由解決問題1開始,不斷由簡到...