欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java C++題解leetcode886可能的二分法并查集染色法

 更新時(shí)間:2022年10月17日 10:23:37   作者:AnjaVon  
這篇文章主要為大家介紹了Java C++題解leetcode886可能的二分法并查集染色法實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

題目要求

思路一:反向點(diǎn)+并查集

  • 根據(jù)題意不喜歡就不在一個(gè)組可以想到使用并查集,本題是兩個(gè)集合所以對(duì)每一個(gè)節(jié)點(diǎn)引入一個(gè)反向點(diǎn),使兩者分屬于不同集合,借此記錄前續(xù)節(jié)點(diǎn)維持的不喜歡關(guān)系;
  • 在將每個(gè)節(jié)點(diǎn)xxx放入組合時(shí),同時(shí)將其反向節(jié)點(diǎn)x+nx+nx+n放入另一組合,然后向后遍歷依次處理每個(gè)節(jié)點(diǎn),同時(shí)判斷相互不喜歡的兩個(gè)點(diǎn)當(dāng)前是否會(huì)被迫放入一個(gè)集合(連通),若是則無(wú)法滿(mǎn)足題意。

下面淺學(xué)一些并查集的基本概念,然后再去實(shí)現(xiàn)思路——

淺學(xué)并查集(Union Find)

學(xué)習(xí)參考鏈接

  • 從介紹到不斷優(yōu)化的整個(gè)構(gòu)造推導(dǎo)過(guò)程,圖片示例與解釋很清晰。

簡(jiǎn)介:

一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并查詢(xún)問(wèn)題;

  • 核心思想:
    • 用一個(gè)數(shù)組表示整片森林,樹(shù)的根節(jié)點(diǎn)唯一標(biāo)識(shí)了一個(gè)集合,只要找到了某個(gè)元素的樹(shù)根,就能確定它在哪個(gè)集合里;
  • 適用場(chǎng)景:
    • 用于需要反復(fù)查找某一元素屬于哪個(gè)集合以進(jìn)行集合合并的場(chǎng)景,用其他數(shù)據(jù)結(jié)構(gòu)解決該類(lèi)問(wèn)題將造成巨大的時(shí)空開(kāi)銷(xiāo)。

基礎(chǔ)操作:

通常包括三個(gè)函數(shù)

函數(shù)功能
find(x)查找元素xxx屬于哪個(gè)集合,也就是找當(dāng)前元素所在樹(shù)的根節(jié)點(diǎn),查找的同時(shí)進(jìn)行路徑壓縮
union(a, b)合并元素aaa和元素bbb所屬集合,根據(jù)樹(shù)高合并兩棵樹(shù)
isConnected(a, b)判斷aaa和元素bbb是否處于同一集合中,也就是判斷二者根是否相同

Java

class Solution {
    int[] p = new int[4010]; // 并查集數(shù)組,存父級(jí)節(jié)點(diǎn)
    // 找當(dāng)前節(jié)點(diǎn)的根
    int find(int x) {
        if(p[x] != x) // 非根節(jié)點(diǎn)
            p[x] = find(p[x]); // 繼續(xù)向下找根并進(jìn)行路徑壓縮
        return p[x];
    }
    // 連接兩節(jié)點(diǎn)的根
    void union(int a, int b) {
        p[find(a)] = p[find(b)];
    }
    // 兩節(jié)點(diǎn)是否連通
    boolean isConnected(int a, int b) {
        return find(a) == find(b);
    }
    public boolean possibleBipartition(int n, int[][] dislikes) {
        for (int i = 1; i <= 2 * n; i++) // 節(jié)點(diǎn)+反向節(jié)點(diǎn)
            p[i] = i; // 初始化并查集,指向自己
        for (int[] cur : dislikes) {
            int a = cur[0], b = cur[1];
            if (isConnected(a, b)) // 連通,被迫在一組
                return false;
            // 利用反向節(jié)點(diǎn)維護(hù)連通關(guān)系
            union(a, b + n);
            union(b, a + n);
        }
        return true;
    }
}
  • 時(shí)間復(fù)雜度:O(n+m),其中m為dislikes的長(zhǎng)度
  • 空間復(fù)雜度:O(n)

C++

  • 注意union會(huì)和C++中的預(yù)定義函數(shù)重名
class Solution {
public:
    int p[4010]; // 并查集數(shù)組,存父級(jí)節(jié)點(diǎn)
    // 找當(dāng)前節(jié)點(diǎn)的根
    int find(int x) {
        if(p[x] != x) // 非根節(jié)點(diǎn)
            p[x] = find(p[x]); // 繼續(xù)向下找根并進(jìn)行路徑壓縮
        return p[x];
    }
    // 連接兩節(jié)點(diǎn)的根
    void unionn(int a, int b) {
        p[find(a)] = p[find(b)];
    }
    // 兩節(jié)點(diǎn)是否連通
    bool isConnected(int a, int b) {
        return find(a) == find(b);
    }
    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        for (int i = 1; i <= 2 * n; i++) // 節(jié)點(diǎn)+反向節(jié)點(diǎn)
            p[i] = i; // 初始化并查集,指向自己
        for (auto cur : dislikes) {
            int a = cur[0], b = cur[1];
            if (isConnected(a, b)) // 連通,被迫在一組
                return false;
            // 利用反向節(jié)點(diǎn)維護(hù)連通關(guān)系
            unionn(a, b + n);
            unionn(b, a + n);
        }
        return true;
    }
};
  • 時(shí)間復(fù)雜度:O(n+m)
  • 空間復(fù)雜度:O(n)

思路二:染色法

  • 將不喜歡數(shù)組存成一個(gè)無(wú)向圖,給分屬兩個(gè)不同集合的點(diǎn)染上不同的顏色,不斷更新染色并判斷不喜歡關(guān)系是否能夠成立;
  • 采用鏈?zhǔn)角跋蛐谴鎯?chǔ)構(gòu)建無(wú)向圖,有邊的兩者不能是同一個(gè)顏色,用1和2表示兩種不同的顏色,用000表示未染色;
  • 定義一個(gè)DFS(node, clr)函數(shù)表示將節(jié)點(diǎn)node染成clr色

Java

class Solution {
    int N = 2010, M = 2 * 10010;
    int[] head = new int[N], edge = new int[M], next = new int[M];
    int[] color = new int[N];
    int idx = 0;;
    void add(int a, int b) {
        edge[idx] = b;
        next[idx] = head[a];
        head[a] = idx++;
    }
    boolean DFS(int node, int clr) {
        color[node] = clr;
        for (int i = head[node]; i != -1; i = next[i]) {
            int j = edge[i];
             // 不喜歡雙方同色
            if (color[j] == clr)
                return false;
            if (color[j] == 0 && !DFS(j, 3 - clr))
                return false;
        }
        return true;
    }
    public boolean possibleBipartition(int n, int[][] dislikes) {
        Arrays.fill(head, -1);
        for (int[] cur : dislikes) { // 構(gòu)建無(wú)向圖
            int a = cur[0], b = cur[1];
            add(a, b);
            add(b, a);
        }
        for (int i = 1; i <= n; i++) {
            if (color[i] != 0) // 已經(jīng)染過(guò)
                continue;
            if (!DFS(i, 1)) // 無(wú)法染色成功
                return false;
        }
        return true;
    }
}
  • 時(shí)間復(fù)雜度:O(n+m)
  • 空間復(fù)雜度:O(n+m)

C++

class Solution {
public:
    static const int N = 2010, M = 2 * 10010;
    int head[N], edge[M], next[M];
    int color[N];
    int idx = 0;;
    void add(int a, int b) {
        edge[idx] = b;
        next[idx] = head[a];
        head[a] = idx++;
    }
    bool DFS(int node, int clr) {
        color[node] = clr;
        for (int i = head[node]; i != -1; i = next[i]) {
            int j = edge[i];
             // 不喜歡雙方同色
            if (color[j] == clr)
                return false;
            if (color[j] == 0 && !DFS(j, 3 - clr))
                return false;
        }
        return true;
    }
    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        memset(head, -1, sizeof(head));
        for (auto cur : dislikes) { // 構(gòu)建無(wú)向圖
            int a = cur[0], b = cur[1];
            add(a, b);
            add(b, a);
        }
        for (int i = 1; i <= n; i++) {
            if (color[i] != 0) // 已經(jīng)染過(guò)
                continue;
            if (!DFS(i, 1)) // 無(wú)法染色成功
                return false;
        }
        return true;
    }
};
  • 時(shí)間復(fù)雜度:O(n+m)
  • 空間復(fù)雜度:O(n+m)

總結(jié)

算法題就回避一下Rust……待我學(xué)成歸來(lái)……

填了拖了好久的并查集的坑還捎帶復(fù)習(xí)了一波鏈?zhǔn)角跋蛐谴鎴D;

感覺(jué)鏈?zhǔn)角跋蛐峭貌畈欢嗔?hellip;…

以上就是Java C++題解leetcode886可能的二分法并查集染色法的詳細(xì)內(nèi)容,更多關(guān)于Java C++ 可能的二分法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MybatisPlus調(diào)用原生SQL的實(shí)現(xiàn)方法

    MybatisPlus調(diào)用原生SQL的實(shí)現(xiàn)方法

    本文主要介紹了MybatisPlus調(diào)用原生SQL的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • JavaScript的基本類(lèi)型值-String類(lèi)型

    JavaScript的基本類(lèi)型值-String類(lèi)型

    String類(lèi)型用于表示由零或多個(gè)16位Unicode字符組成的字符序列,即字符串。在JavaScript中沒(méi)有單個(gè)的字符型,都是字符串。這篇文章主要介紹了JavaScript的基本類(lèi)型值String類(lèi)型,需要的朋友可以參考下
    2017-02-02
  • 如何通過(guò)XML方式配置并實(shí)現(xiàn)Mybatis

    如何通過(guò)XML方式配置并實(shí)現(xiàn)Mybatis

    這篇文章主要介紹了如何通過(guò)XML方式配置并實(shí)現(xiàn)Mybatis,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 一文秒懂logstash收集springboot日志的方法

    一文秒懂logstash收集springboot日志的方法

    通過(guò)這篇文章帶你了解logstash收集springboot日志的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 在Java中實(shí)現(xiàn)線程安全的單例模式的常見(jiàn)方式

    在Java中實(shí)現(xiàn)線程安全的單例模式的常見(jiàn)方式

    單例模式是一種常用的軟件設(shè)計(jì)模式,它確保一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn),在多線程環(huán)境下,確保單例模式的線程安全性是非常重要的,因?yàn)槎鄠€(gè)線程可能會(huì)同時(shí)嘗試創(chuàng)建實(shí)例,導(dǎo)致實(shí)例不唯一的問(wèn)題,本文介紹了在Java中實(shí)現(xiàn)線程安全的單例模式有幾種常見(jiàn)的方式
    2024-09-09
  • @RereshScope刷新的原理詳解

    @RereshScope刷新的原理詳解

    在配合配置中心修改配置讓?xiě)?yīng)用自動(dòng)刷新配置時(shí),我們要在需要感知配置變化的bean上面加上@RereshScope。如果我們不加上這注解,那么有可能無(wú)法完成配置自動(dòng)刷新。本文就來(lái)和大家講講@RereshScope刷新的原理,需要的可以參考一下
    2022-12-12
  • 如何發(fā)布jar包到maven中央倉(cāng)庫(kù)

    如何發(fā)布jar包到maven中央倉(cāng)庫(kù)

    這篇文章主要介紹了發(fā)布jar包到maven中央倉(cāng)庫(kù)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • springboot如何獲取請(qǐng)求者的ip地址

    springboot如何獲取請(qǐng)求者的ip地址

    在Spring框架中,可以使用攔截器(Interceptor)來(lái)監(jiān)聽(tīng)每個(gè)控制器(Controller)的請(qǐng)求,并記錄請(qǐng)求者的IP地址,這篇文章主要介紹了springboot如何獲取請(qǐng)求者的ip地址,需要的朋友可以參考下
    2024-07-07
  • 教你輕松制作java視頻播放器

    教你輕松制作java視頻播放器

    這篇文章主要為大家詳細(xì)介紹了如何編寫(xiě)屬于自己的java視頻播放器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Java自定義比較器實(shí)現(xiàn)中文排序

    Java自定義比較器實(shí)現(xiàn)中文排序

    這篇文章主要介紹了Java自定義比較器實(shí)現(xiàn)中文排序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08

最新評(píng)論