最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java并查集算法帶你領(lǐng)略熱血江湖

 更新時(shí)間:2021年11月09日 10:07:21   作者:愛(ài)敲代碼的小黃  
這篇文章主要為大家介紹了java并查集算法,以大家熱愛(ài)的方式,帶你領(lǐng)略熱血江湖中的并查集算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助

你好,我是小黃,一名獨(dú)角獸企業(yè)的Java開(kāi)發(fā)工程師。
校招收獲數(shù)十個(gè)offer,年薪均20W~40W。
感謝茫茫人海中我們能夠相遇,
俗話說(shuō):當(dāng)你的才華和能力,不足以支撐你的夢(mèng)想的時(shí)候,請(qǐng)靜下心來(lái)學(xué)習(xí),
希望優(yōu)秀的你可以和我一起學(xué)習(xí),一起努力,實(shí)現(xiàn)屬于自己的夢(mèng)想。

一、什么是并查集

并查集被很多OIer認(rèn)為是最簡(jiǎn)潔而優(yōu)雅的數(shù)據(jù)結(jié)構(gòu)之一,主要用于處理一些不相交集合的合并問(wèn)題,并支持兩種操作:

  • 合并(Union):把兩個(gè)不相交的集合合并為一個(gè)集合。
  • 查詢(Find):查詢兩個(gè)元素是否在同一個(gè)集合中。

當(dāng)然,這樣的定義讓人感覺(jué)摸不著頭腦,我們來(lái)一個(gè)樣例進(jìn)行分析。

二、深入理解并查集

在遙遠(yuǎn)的江湖,有一群武俠人,他們各自為戰(zhàn),守護(hù)著自己該守護(hù)的東西。

  • 1號(hào):擅長(zhǎng)刀、武力值98
  • 2號(hào):擅長(zhǎng)劍、武力值95
  • 3號(hào):擅長(zhǎng)棍、武力值93
  • 4號(hào):擅長(zhǎng)槍、武力值90

突然有一天,一個(gè)不速之客(小黃)來(lái)到了這個(gè)江湖,想要稱霸江湖,一場(chǎng)腥風(fēng)血雨的戰(zhàn)斗即將拉開(kāi)序幕。

  • 小黃:擅長(zhǎng)機(jī)關(guān)槍、武力值100、寶物:并查集

江湖的局面被五人分割,如下圖所示:

  • 箭頭的含義:自己的大哥(比如2號(hào)的箭頭指向自己,那2號(hào)的大哥就是他自己)

在這里插入圖片描述

小黃看到其余4人的資料后,使用寶物并查集查詢了一下4號(hào)和其余幾人的關(guān)系,發(fā)現(xiàn)4號(hào)是孤膽一人, 決定從4號(hào)先入手。

在一個(gè)月黑風(fēng)高的晚上,小黃拿著機(jī)關(guān)槍,使用寶物并查集的合并,把4號(hào)進(jìn)行收服,成為其小弟。

1號(hào)、2號(hào)、3號(hào)聽(tīng)聞昨夜4號(hào)被收服,立刻舉行會(huì)議商討合作的事情,1號(hào)由于身高氣傲,不想要與另外兩人合作,2號(hào)、3號(hào)只好進(jìn)行合作。

于是,江湖的局面又發(fā)生了變化。

在這里插入圖片描述

小黃的野心可是稱霸江湖,于是使用寶物并查集分別查詢了1號(hào)、2號(hào)、3號(hào)的目前狀態(tài),得知:1號(hào)還是獨(dú)膽一人,而2、3號(hào)已經(jīng)結(jié)盟。

小黃又在一個(gè)夜黑風(fēng)高的晚上與1號(hào)大戰(zhàn)一夜,最終使用寶物并查集的合并,收服了1號(hào)。

至此,江湖只存在兩個(gè)派系,2號(hào)派系、小黃派系。

2號(hào)察覺(jué)到了目前小黃的勢(shì)力,主動(dòng)擺宴,希望江湖不在打打殺殺,能夠平安無(wú)事。

在宴上,由于2號(hào)派系的人數(shù)小于小黃派系的人數(shù),于是,2號(hào)派系正式被小黃派系吞噬,江湖正式統(tǒng)一。

在這里插入圖片描述

三、實(shí)現(xiàn)并查集

并查集的初始化:

class UnionAndFind() {
    // 自己的大哥是誰(shuí)
    private int[] parent;
    // 自己的隊(duì)伍有多少人
    private int[] size;
    // 江湖還有幾個(gè)派系
    int sets;

    // 初始化
    // 每個(gè)人的大哥都是自己
    // 每個(gè)隊(duì)伍的人數(shù)都為1
    public UnionAndFind(int N) {
        parent = new int[N];
        size = new int[N];
        help = new int[N];
        sets = N;
        for (int i = 0; i < N; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }
}

并查集的 查詢(Find) 方法:這里的時(shí)間復(fù)雜度可以降低到O(1)級(jí)別,不敢相信吧,那就往下看吧。

	// 查詢a和b在不在一個(gè)陣營(yíng)中
	public boolean isSameSet(int a, int b) {
        return find(a) == find(b);
    }
	// 看一下你的最終大哥是誰(shuí)
    public int find(int i){
        while(i != parent[i]){
            i = parent[i];
        }
        return i;
    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

并查集的 合并(Union)方法:先去找到兩個(gè)參數(shù)的最終大哥,小弟少的大哥跟著小弟多的大哥混

	public void union(int a, int b) {
        int A = find(a);
        int B = find(b);
        if (A != B) {
            if (size[A] >= size[B]) {
                size[A] += size[B];
                parent[B] = A;
            } else {
                size[B] += size[A];
                parent[A] = B;
            }
            sets--;
        }
    }

四、真題訓(xùn)練

547. 省份數(shù)量

初始化數(shù)組,拷貝上述并查集即可

public int findCircleNum(int[][] isConnected) {
        int N = isConnected.length;
        UnionAndFind unionFind = new UnionAndFind(N);
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (isConnected[i][j] == 1 && i != j) {
                    unionFind.union(i, j);
                }
            }
        }
        return unionFind.sets;
    }

在這里插入圖片描述

五、路徑壓縮優(yōu)化

我們目前的并查集已經(jīng)可以解決大部分問(wèn)題,但是,我們能夠?qū)δ壳暗牟⒉榧姹具M(jìn)行路徑壓縮優(yōu)化。

我們可以發(fā)現(xiàn),在我們 find() 方法時(shí),我們會(huì)進(jìn)行一個(gè) while() 循環(huán)的查找大哥的操作,這種操作十分的浪費(fèi)時(shí)間,有沒(méi)有什么辦法可以進(jìn)行下優(yōu)化呢?

如下所示:

在這里插入圖片描述

我們可以看到對(duì)于6、5、3之類來(lái)說(shuō),每次進(jìn)行 find 查詢的時(shí)候,都需要經(jīng)過(guò)2~3次的循環(huán)才能夠找到1。

如果我們?cè)谶M(jìn)行查找的時(shí)候,保存一下值,然后重新掛到1的上面,比如:

我要查詢下6,肯定會(huì)查詢找5、3,這個(gè)時(shí)候,我們把6、5、3保存到臨時(shí)數(shù)組中,在查詢完畢后,將這些數(shù)組直接掛到1的下面,這樣的話,下次查詢會(huì)降低循環(huán)的次數(shù)。

在這里插入圖片描述

當(dāng)我們查詢的次數(shù)遠(yuǎn)遠(yuǎn)大于我們的數(shù)據(jù)量時(shí),這個(gè)時(shí)候 find() 的操作就已經(jīng)變成了一個(gè)O(1)級(jí)別的查詢時(shí)間。

public int find(int i) {
        int h = 0;
        while (i != parent[i]) {
            help[h++] = i;
            i = parent[i];
        }
        for (h--; h >= 0; h--) {
            parent[help[h]] = i;
        }
        return i;
    }

六、總結(jié)

并查集算法通常用在處理一些不交集(Disjoint Sets)的合并及查詢問(wèn)題

力扣也有并查集的 tag 專欄:并查集

大家可以好好體會(huì)一下路徑壓縮的奇妙,通過(guò)不斷的路徑壓縮,可以將我們的時(shí)間復(fù)雜度降低到O(1)

這里可能有小伙伴有疑問(wèn),為啥是O(1),你就算掛在1的下面,不也得查詢兩次嘛

對(duì)于時(shí)間復(fù)雜度來(lái)說(shuō),只要是常數(shù)的次數(shù)都可以認(rèn)定為O(1)的時(shí)間復(fù)雜度,況且,你也可以使用HashMap來(lái)進(jìn)行存儲(chǔ)。

以上就是java并查集算法帶你領(lǐng)略熱血江湖的詳細(xì)內(nèi)容,更多關(guān)于java并查集算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java花式解決'分割回文串 ii'問(wèn)題詳解

    Java花式解決'分割回文串 ii'問(wèn)題詳解

    最學(xué)習(xí)動(dòng)態(tài)規(guī)劃思想的路上,遇見(jiàn)了‘分割回文串問(wèn)題’,如臨大敵啊,題目聽(tīng)起來(lái)蠻簡(jiǎn)單,思考起來(lái)卻也沒(méi)那么容易,本文將為大家詳細(xì)介紹幾種解決分割回文串 ii問(wèn)題的辦法,需要的可以參考一下
    2021-12-12
  • spring boot 常見(jiàn)http請(qǐng)求url參數(shù)獲取方法

    spring boot 常見(jiàn)http請(qǐng)求url參數(shù)獲取方法

    這篇文章主要介紹了spring boot 常見(jiàn)http請(qǐng)求url參數(shù)獲取,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 功能強(qiáng)大的TraceId?搭配?ELK使用詳解

    功能強(qiáng)大的TraceId?搭配?ELK使用詳解

    這篇文章主要為大家介紹了功能強(qiáng)大的TraceId?搭配?ELK使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java編程實(shí)現(xiàn)統(tǒng)計(jì)數(shù)組中各元素出現(xiàn)次數(shù)的方法

    Java編程實(shí)現(xiàn)統(tǒng)計(jì)數(shù)組中各元素出現(xiàn)次數(shù)的方法

    這篇文章主要介紹了Java編程實(shí)現(xiàn)統(tǒng)計(jì)數(shù)組中各元素出現(xiàn)次數(shù)的方法,涉及java針對(duì)數(shù)組的遍歷、比較、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • Java基礎(chǔ)之代理原理與用法詳解

    Java基礎(chǔ)之代理原理與用法詳解

    這篇文章主要介紹了Java基礎(chǔ)之代理原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了java代理的概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • 深入學(xué)習(xí)java中的Groovy 和 Scala 類

    深入學(xué)習(xí)java中的Groovy 和 Scala 類

    本文將探討三種下一代 JVM 語(yǔ)言:Groovy、Scala 和 Clojure,比較并對(duì)比新的功能和范例,讓 Java 開(kāi)發(fā)人員對(duì)自己近期的未來(lái)發(fā)展有大體的認(rèn)識(shí)。,需要的朋友可以參考下
    2019-06-06
  • Java編程基本概念

    Java編程基本概念

    本文主要介紹了Java編程的基本概念,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 對(duì)arraylist中元素進(jìn)行排序?qū)嵗a

    對(duì)arraylist中元素進(jìn)行排序?qū)嵗a

    這篇文章主要介紹了對(duì)arraylist中元素進(jìn)行排序?qū)嵗a,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • 解讀什么是構(gòu)造方法?能否被重寫或重載?

    解讀什么是構(gòu)造方法?能否被重寫或重載?

    這篇文章主要介紹了什么是構(gòu)造方法?能否被重寫或重載問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04

最新評(píng)論

介休市| 伊春市| 广水市| 金坛市| 涿鹿县| 乌审旗| 克拉玛依市| 朔州市| 乳源| 紫阳县| 长寿区| 肥东县| 屯留县| 韩城市| 罗田县| 赤峰市| 桂林市| 和林格尔县| 绥中县| 象州县| 邯郸县| 湘潭县| 芷江| 宁德市| 宁陕县| 绍兴市| 德江县| 宣化县| 抚顺市| 谷城县| 盐源县| 青海省| 太和县| 鹤壁市| 师宗县| 汉阴县| 中卫市| 乌拉特中旗| 镇江市| 青田县| 社旗县|