利用完全二叉樹快速求解LCA

來源:互聯網
上載者:User

以下內容是從AekdyCoin的一篇文章裡看到的,源處處不明,只是感到很神奇,尚未發現用武之地。

下面所說的演算法由於相比於Tarjan和nlogn的做法會複雜一些,因此用的也不多。不過出於好奇,我還是研究了一下。

眾所周知,lca和rmq就像情侶一樣關係緊密。lca可以由dfs一次轉化為+1rmq問題,而+1rmq是可以用O(nlogn)-O(1)或O(n)-O(1)做出來的,不過寫起來會比較麻煩而且細節很多,具體的做法就不贅述了。

接下來要講的O(n)-O(1)線上lca的演算法和rmq沒有絲毫關係,而且演算法簡潔,實現簡單,除了證明複雜之外。不過證明再複雜也沒影響,因為在用的時候直接套是不需要考慮太多證明的,所以理解即可。
首先介紹一下完全二叉樹上的lca的求解。

上面這個圖給出了15個點的完全二叉樹,所有節點按照樹的中序遍曆分配編號,編號從1開始。在這棵樹上的lca是怎樣的形態?

注意到,這棵樹從根節點往下,每個節點末尾連續的0個數依次遞減。對於任意一個點x,設它末尾連續的0的個數是k個,那麼它的子樹有2k+1-1個節點,而且左右子樹分別是2k-1個。同時,每個孩子的編號除了後k+1位可能和x不同外,首碼完全相同。其中,左子樹的第k位是0,右子樹的第k為是1。即如果x
= “a1b”,a是任意01串,b是連續的k個0,那麼x的子樹中的節點的結構式”ac”,c是長度為k+1的任意01串。
哈!聰明的你肯定可以發現,在這樣的完全二叉樹上,任意兩個點的的lca可以用位元運算很快的求出來:設兩點的中序編號為x和y以及他們的lca為r,令z = x ^ y(按位異或),k為z二進位表示中最靠左的1的位置,那麼r的k左邊的部分是和x、y相同的(因為異或),而第k位是1,k右邊都是0。
上面所說的那個規律很好發現,只是描述起來很複雜而已- -|||。即,如果認為位元運算的操作時間是常數時間,那麼在完全二叉樹中任意兩個節點的lca就可以在O(1)內解決。但是通常的lca問題是任意給定的樹,結構不一定是二叉的。這個完全二叉樹的做法能對我們有什麼協助呢?

如果我們能夠找到一種映射關係將兩者聯絡起來,即將lca的查詢轉化到完全二叉中,也就可以做到O(1)了。這裡要說的映射方法是這樣的:
首先定義函數h(x)為數x的二進位表示中末尾連續的0的個數,也稱之為x的高度。
       1.    對整棵樹進行先序遍曆(為什嗎?)分配編號;
       2.    對於每個點x,求出以它為根的子樹中所有節點的最大的h函數值,設這個值為I(x)。

這幅圖給了一個分配編號以及求I(x)的例子。注意到在圖中有紅色標記的路徑上的每個點的I值是相同的,都等於路徑中深度最大的那個點的h函數值,這個值同時也是它的I值。為什麼是這樣的?有個比較明顯的結論,父親的I值始終不小於兒子的I值。那麼紅色路徑的性質的原因也就不難理解了。需要注意的是,在一棵子樹中h函數值最大的點有且只有一個。

到這一步就說我們將一般lca問題和完全二叉樹lca結合了起來還為時尚早。下面給出一個極為重要的結論:
如果z是x的祖先,那麼I(z)在完全二叉樹中也是I(x)的祖先(樹中一個節點也可以理解為自己的祖先)。
證明:    首先有I(z) ≥ I(x)。如果I(z) = I(x),那麼結論顯然成立。
對於I(z) > I(x)的情況,令h(I(z)) = i。假設在第i位的左邊存在某一個位置k(k > i),I(z)和I(x)在k的左邊每一位相同,而在第k位它們倆不一樣,那麼因為I(z) > I(x),所以I(z)在第k位是1,而I(x)
在這一位是0。那麼肯定存在一個N使得I (x) < N < I(z),這個N的第k位以及其左邊與I(z)相同,而N的第k位右邊全部為0。因為我們的編號分配過程是先序編號,那麼N肯定出現在z的子樹中,根據I值的定義,有h(N) <= h(I(N)) < h(I(z))。可是之前假設有h(N) = k > i = h(I(z)),產生了矛盾。
因此不存在這樣的k,即,I(z)和I(x)在第i位左邊完全一樣。由於I(z) 在第i位上是1,I(x)是0,因此根據之前給的完全二叉樹的性質可以得知I(z)是I(x)的祖先。

那麼可以確定的是,x和y的lca(設為z)的I值肯定是I(x)和I(y)共同的祖先。
我們將x和y到根節點的路徑分別反向列出來(如給出了節點7和節點10的路徑),可以發現它們有個公用的首碼,其實這一段就是由它們的公用祖先組成的,而最靠後的就是z。在路徑序列中從前往後各個點I值的高度依次不降。在完全二叉樹中,我們可以求出一個點在任意高度的祖先,那麼如果我們能夠確定I(z)的高度,也就可以相應得到I(z)了。I(z)的高度該怎麼算呢?

按照在樹中求I值的方法我們知道,樹中出現的I值只是完全二叉樹中的一個子集,有些數值並沒有取到。比如2如果是8的父親,那麼2(0010)這個值是不會在I中出現的。那麼點到根節點的路徑序列中的I值並不像完全二叉樹中那樣連續的。因此,為了方便處理,我們需要把節點到根節點路徑上所有I值的高度資訊存下來。這個是很好實現的,用二進位串來表示在這個節點的祖先中某一個高度是否達到即可,由於樹的規模一般不會太大,用一個32位int來存完全足夠了,我們用A(x)來表示這個數。
令I(x)和I(y)的lca的高度是i,然後j是A(x)和A(y)兩個01串的高位中連續相同的最靠後的位置,不難證明h(I(z)) = j ≥ i。由此,I(z)也就求出來了。

現在我們所需要做的工作就是找到這個z。I值等於I(z)可能會有很多個,但是哪一個才是我們想要的呢?之前在樹上求I值的時候被特意標記過那條紅色的路徑就是所有I值相等的一條鏈,同時,那樣的一個I值也只會出現在這個鏈上。因此,最後其實就是在I(z)的那條臉上找答案了。
節點x和y必然都是在z的子樹裡面的,而x和y在I(z)鏈上的最近的祖先,分別令為x’和y’,其實它倆就是我們的備選答案。如果I(x) = I(z),那麼顯然x’就等於x本身;如果不等又該怎麼辦呢?

可以稍微拐彎抹角一下。比如上面的7和10的情況,10在I(z)中的最近祖先是2,可是在只知道I(z) = “1000”的情況下,這個2的位置並不好確定。雖然如此,2的兒子9確是好找到的,因為9,在I值等於”1010”所對應的鏈中是出於最上方的位置。如果我們實現將每條I值鏈最上方的節點在預先處理中計算出來,那麼就可以很快的找到了x’和y’在各自到x和y的路徑中的兒子了,因為那倆兒子的I值是很容易得到的。也就是說,我們通過先找到x’和y’的兒子就可以找到x’和y’了。而最後的答案z其實就是x’和y’中深度較小的那個。


自此,我們就將整個問題完美的解決了。下面將步驟總結一下:
1. 預先處理:
a) dfs先序遍曆分配編號(其實後序遍曆也行,但是中序卻不可以),記錄每個點的父親;
b) 計算出每個點的I值以及對應的A值,同時對每條I值對應的鏈記錄深度最小的節點編號;
2. 對於給定詢問x和y,找出I(x)和I(y)的lca並求出該數的高度i;
3. 在i的限制下利用A(x)和A(y)求出I(z)的高度j,並由此得出I(z);
4. 計算x’:如果I(x) = I(z),那麼x’ = x;反之,求出x的高度低於j的最大的高度k,算出x的高度為k的祖先中深度最淺的點w,那麼x’ 就是w的父親;
5. 用和步驟4相同的方法計算y’;z就是x’和y’中深度較小的點。
上面的演算法預先處理用兩次dfs即可實現,複雜度都是O(n),而之後的查詢基於位元運算以及之前與處理的結果的從而達到O(1)。代碼中涉及到比較多的位元運算,不過code長度很短,和離線的Tarjan一樣都很簡潔。



是的,這樣的做法不是普通人能想出的,要麼那人是神級的,要麼他就是各種拼湊了N多天才搞出了這樣演算法。演算法中的那個從一般lca問題向完全二叉樹映射著實會讓人摸不著頭腦,而只有在知曉了所有步驟之後才會發現那樣的轉化是多麼的精妙,然後各種感慨。另外,整個做法的正確性需要大量的證明,幾乎每一次轉化都需要利用很多特殊的性質。總之,這個線上的演算法是各種詭異、各種神奇。不過這些都不影響我們來享受這個演算法所帶來的美感以及便利。至少,它給出了一種解決問題的很好的思路,就是將問題向經典問題靠攏、映射並統一,這個想法能充分利用先有知識並利用它們來學習更多

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.