Quick Union

直覺描述

依舊是動態(tài)聯(lián)通性問題简逮。換一種方法來處理。

圖1: 動態(tài)聯(lián)通性問題-簡單

Quick Union

與Quick Find一樣蒜胖,我們需要用到index今缚。

針對節(jié)點(diǎn)算柳,有[0, 1, ...9]作為index。

看看有哪些連接荚斯。

union(0, 1), union(1, 2), union(0, 5), union(1, 6), 
union(2, 7), union(3, 4), union(3, 8), union(4, 9)

Quick Find使用的方式是埠居,將聯(lián)通的節(jié)點(diǎn)index改為一樣的,所以更新后的index可以分為若干組事期,每個(gè)組內(nèi)的index是相同的,每個(gè)組表示相互聯(lián)通的節(jié)點(diǎn)組合纸颜。組員間的關(guān)系可以看作是平級的兽泣。

Quick Union使用的方式是,將聯(lián)通的節(jié)點(diǎn)之間用父子關(guān)系串聯(lián)起來胁孙,所以組員間的關(guān)系可以看作是樹狀的唠倦。

為了方便起見,我們將每次union(m, n)定義為涮较,m為稠鼻,n為。每次union狂票,都是用m所代表的組的頂部候齿,即父節(jié)點(diǎn),連接到n節(jié)點(diǎn)所代表的組的父節(jié)點(diǎn)之下闺属,這樣慌盯,m所代表的這一組有了新的頂部節(jié)點(diǎn),也就是n那一組的父節(jié)點(diǎn)掂器。整個(gè)過程如下面的示例分步進(jìn)行:

  • union(0, 1)
    圖2: union(0, 1)

    index更新為:
[1亚皂,1,2国瓮,3灭必,4,5乃摹,6禁漓,7,8峡懈,9]
  • union(1, 2)
    圖3: union(1, 2)

    index更新為:
[1璃饱,2,2肪康,3荚恶,4撩穿,5,6谒撼,7食寡,8,9]
  • union(0, 5)
    圖4: union(0, 5)

    index更新為:
[1廓潜,2抵皱,5,3辩蛋,4呻畸,5,6悼院,7伤为,8,9]
  • union(1, 6)
    圖5: union(1, 6)

    index更新為:
[1据途,2绞愚,5,3颖医,4位衩,6,6熔萧,7糖驴,8,9]
  • union(2, 7)
    圖6: union(2, 7)

    index更新為:
[1哪痰,2遂赠,5,3晌杰,4跷睦,6,7肋演,7抑诸,8,9]
  • union(3, 4)
    圖7: union(3, 4)

    index更新為:
[1爹殊,2蜕乡,5,4梗夸,4层玲,6,7,7辛块,8畔派,9]
  • union(3, 8)
    圖8: union(3, 8)

    index更新為:
[1,2润绵,5线椰,4,8尘盼,6憨愉,7,7卿捎,8配紫,9]
  • union(4, 9)
    圖9: union(4, 9)

    index更新為:
[1,2娇澎,5笨蚁,4,8趟庄,6,7伪很,7戚啥,9,9]

接下來就很好辦锉试,如果我們想知道兩個(gè)節(jié)點(diǎn)是否聯(lián)通猫十,只需要查詢它們所屬的頂端父節(jié)點(diǎn)是否相同就可以了。比如:

connected(2, 3) = false
2的頂端父節(jié)點(diǎn)是7呆盖,3的頂端父節(jié)點(diǎn)是9拖云,因此它們不聯(lián)通;

復(fù)雜度

接下來我們看一下Quick Union的復(fù)雜度应又。這種方法做了如下的事情宙项,和Quick Find一樣:

  • 給每一個(gè)節(jié)點(diǎn)初始index;
  • 記錄union株扛;
  • 查詢聯(lián)通性尤筐;
    代碼如下:
public class QuickUnionUF
{
  private int[] id;
  public QuickUnionUF(int N)
  {
    id = new int[N];
    for (int i = 0; i < N; i++) id[i] = i;
  }
  private int root(int i)
  {
    while (i != id[i]) i = id[i];
    return i;
  }
  public boolean connected(int p, int q)
  {
    return root(p) == root(q);
  }
  public void union(int p, int q)
  {
    int i = root(p);
    int j = root(q);
    id[i] = j;
  }
}

給每一個(gè)節(jié)點(diǎn)初始index;

用到的是constructor中的for循環(huán)洞就,即:

for (int i = 0; i < N; i++)
    id[i] = i;

很明顯盆繁,這里訪問了index對象N次。

記錄union

如下旬蟋,可以發(fā)現(xiàn)每一次union操作油昂,都涉及到一個(gè)root方法

private int root(int i)
  {
    while (i != id[i]) i = id[i];
    return i;
  }
public void union(int p, int q)
  {
    int i = root(p);
    int j = root(q);
    id[i] = j;
  }

首先看看root這個(gè)方法,它用來查詢一個(gè)節(jié)點(diǎn)的父節(jié)點(diǎn)。那么這個(gè)查詢需要的計(jì)算量冕碟,取決于節(jié)點(diǎn)所在組的樹的深度拦惋。比如0節(jié)點(diǎn)所在的組,深度為6鸣哀,那么前面的計(jì)算步驟union(0, 5)架忌,需要的計(jì)算量如下:

// root(0)
// i = 0
while (0 != id[0] = 1) i = 1;
while (1 != id[1] = 2) i = 2;
while (2 = id[2] = 2)
  return 2
// root(5)
// i = 5
while (5 = id[5] = 5) 
  return 5
// id[0] = 5
可以發(fā)現(xiàn),計(jì)算量 = 3(當(dāng)前tree深度) + 1(當(dāng)前tree深度) + 1 = 5

考慮到樹的深度有可能為N我衬,比較Quick Find和Quick Union叹放,那么出現(xiàn)了如下的復(fù)雜度局面。

圖10: 計(jì)算量比較

那也就是說挠羔,考慮到N次的union操作井仰,Quick Union也需要N2的計(jì)算復(fù)雜度,依舊是個(gè)不好的方法破加,Quick Find無法規(guī)木愣瘢化的問題依舊存在。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末范舀,一起剝皮案震驚了整個(gè)濱河市合是,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锭环,老刑警劉巖聪全,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辅辩,居然都是意外死亡难礼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門玫锋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛾茉,“玉大人,你說我怎么就攤上這事撩鹿∏妫” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵三痰,是天一觀的道長吧寺。 經(jīng)常有香客問我,道長散劫,這世上最難降的妖魔是什么稚机? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮获搏,結(jié)果婚禮上赖条,老公的妹妹穿的比我還像新娘失乾。我一直安慰自己,他們只是感情好纬乍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布碱茁。 她就那樣靜靜地躺著,像睡著了一般仿贬。 火紅的嫁衣襯著肌膚如雪纽竣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天茧泪,我揣著相機(jī)與錄音蜓氨,去河邊找鬼。 笑死队伟,一個(gè)胖子當(dāng)著我的面吹牛穴吹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗜侮,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼港令,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锈颗?” 一聲冷哼從身側(cè)響起顷霹,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎击吱,沒想到半個(gè)月后泼返,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姨拥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渠鸽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叫乌。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖徽缚,靈堂內(nèi)的尸體忽然破棺而出憨奸,到底是詐尸還是另有隱情,我是刑警寧澤凿试,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布排宰,位于F島的核電站,受9級特大地震影響那婉,放射性物質(zhì)發(fā)生泄漏板甘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一详炬、第九天 我趴在偏房一處隱蔽的房頂上張望盐类。 院中可真熱鬧,春花似錦、人聲如沸在跳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猫妙。三九已至瓷翻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間割坠,已是汗流浹背齐帚。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留韭脊,地道東北人童谒。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像沪羔,于是被迫代替她去往敵國和親饥伊。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本系列博客習(xí)題來自《算法(第四版)》蔫饰,算是本人的讀書筆記琅豆,如果有人在讀這本書的,歡迎大家多多交流篓吁。為了方便討論精续,本...
    kyson老師閱讀 1,595評論 0 49
  • 本系列博客習(xí)題來自《算法(第四版)》,算是本人的讀書筆記箍铲,如果有人在讀這本書的拨齐,歡迎大家多多交流。為了方便討論盛嘿,本...
    kyson老師閱讀 2,062評論 0 48
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)洛巢。 張土汪:刷leetcod...
    土汪閱讀 12,747評論 0 33
  • 直覺描述 有種問題叫動態(tài)聯(lián)通性問題。 比如上圖中的節(jié)點(diǎn)圖次兆,可以看到其中一部分被直接或間接連接起來了稿茉,比如: 但有些...
    匿稱也不行閱讀 839評論 0 0
  • 月,從古至今都是文人墨客的寵兒芥炭±炜猓《春江花月夜》的月大氣唯美,《月下獨(dú)酌》的月悲涼曠達(dá)园蝠;巴金先生的《月》清冷...
    朝霞ZX閱讀 344評論 0 0