【算法與數據結構】并查集詳解+題目

目錄

一,什么是并查集

二,并查集的結構?

三,并查集的代碼實現?

1,并查集的大致結構和初始化

2,find操作?

3,Union操作

4,優化?

小結:

四,并查集的應用場景

省份數量[OJ題]?


一,什么是并查集

核心概念:并查集是一種 用于管理元素分組?的數據結構。

在一些應用問題中,需將n個不同的元素劃分成一些不相交的集合,開始時,n個元素各自成一個集合,然后按照一定規律將部分集合合成一個集合,也就是集合合并并查集(union-find)適合來描述這類問題。

對于并查集,我們可以將它看成是一個森林,森林是由多棵樹組成的,并查集中的一個個集合就可以看作是樹。

示例:

二,并查集的結構?

并查集的存儲結構和樹的雙親表示法相似。

所謂雙親表示法,就是在樹的節點中,只存儲父節點的指針,不存儲孩子節點的指針。通過指針可以找到父節點。因為對于一顆樹來說,可能有多個孩子 ,但只有一個父節點。

?

對于上圖中:

節點0的數組值為-4,說明該節點為根節點。

節點6的數組值為0,說明該節點的父節點為0。

節點7的數組值為0,說明該節點的父節點為0。

節點8的數組值為0,說明該節點的父節點為0。

三,并查集的代碼實現?

并查集主要支持一下操作:

  • 查詢(find),查詢一個元素在哪個集合中。
  • 合并(union),將兩個集合合并為一個。

1,并查集的大致結構和初始化

class UnionFind
{
public:
?? ?UnionFind(size_t n)
?? ??? ?:_ufs(n,-1)
?? ?{}

?? ?//......
private:
?? ?vector<int> _ufs;
};

2,find操作?

在并查集中找到包含x的根

int findRoot(int x)
{
?? ?int root = x;

?? ?while (_ufs[root] >= 0)
?? ??? ?root = _ufs[root];

?? ?return root;
}
?

3,Union操作

合并兩個集合

void Union(int x1, int x2)
{
?? ?int root1 = findRoot(x1);
?? ?int root2 = findRoot(x2);
?? ?if (root1 == root2)
?? ??? ?return; //在同一個集合中

?? ?//這里在合并的時候采用數據量小的向數據量大的合并
?? ?//也就是小樹向大樹合并
?? ?if (abs(_ufs[root1]) < abs(_ufs[root2]))//root1節點更少
?? ?{
?? ??? ?_ufs[root2] += _ufs[root1];
?? ??? ?_ufs[root1] = root2; ? //小樹合并到大樹
?? ?}
?? ?else
?? ?{
?? ??? ?//root2節點更少
?? ??? ?_ufs[root1] += _ufs[root2];
?? ??? ?_ufs[root2] = root1;
?? ?}
}

4,優化?

當樹比較高時,我們在反復查某個節點的根節點時,每次都會花費大量時間。

優化方法路徑壓縮,只要查找某個節點一次,就將查找路徑上的所有節點掛到根節點下面。

如圖:查找D的根A,查找路徑上包含節點B,將節點D和節點B直接掛在根節點A的下面。

//路徑壓縮
int findRoot(int x)
{int root = x;while (_ufs[root] >= 0)root = _ufs[root];//路徑壓縮while (_ufs[x] >= 0){int parent = _ufs[x];_ufs[x] = root; ? //掛在根節點的下面x = parent;}return root;
}

小結:

上述實現的并查集,支持連續元素。如果是處理非連續元素,需要使用哈希表代替數組(需額處理元素與索引的映射)。

核心思路:

  • 哈希映射unordered_map將任意類型元素映射為連續整數ID,內部用數組管理父節點
  • 動態擴容:自動添加新元素,無需預先指定規模。

  • 模板化:支持泛型數據類型(如string等)。

四,并查集的應用場景

  1. 連通性檢測:判斷網絡中兩個節點是否連通。

  2. 最小生成樹(Kruskal算法):動態合并邊,避免環。

  3. 社交網絡分組:快速合并好友關系,查詢是否屬于同一社交圈。

總結:

并查集通過高效的查找與合并操作,成為處理動態連通性問題的核心數據結構。其優化方法(路徑壓縮、按秩合并)確保了接近常數的單次操作時間復雜度,適用于大規模數據場景。

其中的按秩合并就是合并集合時小樹向大樹合并。

省份數量[OJ題]?

題目鏈接:LCR 116. 省份數量 - 力扣(LeetCode)

?isConnected[i][j]=1,表示城市i和j連通,連通的城市為一個省份。用并查集將連通的數據放入一個集合,再統計最后的集合個數即可。

class Solution {
public:int findCircleNum(vector<vector<int>>& isConnected) {int n=isConnected.size();vector<int> _ufs(n,-1);//查找根auto find=[&](int x)->int{int root=x;while(_ufs[root]>=0)root=_ufs[root];return root;};for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(isConnected[i][j]==1){//合并i和j集合int rooti=find(i),rootj=find(j);if(rooti!=rootj){_ufs[rooti]+=_ufs[rootj];_ufs[rootj]=rooti;}}}//統計集合數int ret=0;for(auto x:_ufs){if(x<0)ret++;}return ret;}
};

冗余連接[OJ題]

題目鏈接:684. 冗余連接 - 力扣(LeetCode)

class Solution {
public:vector<int> findRedundantConnection(vector<vector<int>>& edges) {//遍歷edges數組//將在同一條邊中的兩個頂點放入一個集合//如果這條邊的兩個頂點已經在同一個集合中,加入這條邊后,會出現環 ,返回這條邊vector<int> ufs(1010);int sz=edges.size();//初始化時各元素自成一個集合,自己就是根for(int i=0;i<sz;i++)ufs[i]=i;for(int j=0;j<sz;j++){//找到邊的兩個頂點所在的集合,也就是根節點int root1=find(edges[j][0],ufs);int root2=find(edges[j][1],ufs);//如果在一個集合,加入這條邊后,會出現環if(root1==root2)return edges[j];else{//兩個集合獨立,合并兩個集合ufs[root1]=root2;}}return {0,0};}int find(int num,vector<int>& ufs){int root=num;while(ufs[root]!=root)root=ufs[root];return root;}
};

等式方程的可滿足性[OJ題]

本題鏈接:990. 等式方程的可滿足性 - 力扣(LeetCode)

class Solution {
public:bool equationsPossible(vector<string>& equations) {//并查集vector<int> ufs(26,-1);auto findroot=[&](int x){int parent=x;while(ufs[parent]>=0)parent=ufs[parent];return parent;};//將相等的放入同一集合中for(auto& str:equations)if(str[1]=='='){int root1=findroot(str[0]-'a');int root2=findroot(str[3]-'a');if(root1!=root2){ufs[root1]+=ufs[root2];ufs[root2]=root1;}}//遇到!,如果在同一個集合,返回falsefor(auto& str:equations){if(str[1]=='!'){int root1=findroot(str[0]-'a');int root2=findroot(str[3]-'a');if(root1==root2)return false;}}return true;}
};

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895578.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895578.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895578.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言簡單練習題

文章目錄 練習題一、計算n的階乘bool類型 二、計算1!2!3!...10!三、計算數組arr中的元素個數二分法查找 四、動態打印字符Sleep()ms延時函數system("cls")清屏函數 五、模擬用戶登錄strcmp()函數 六、猜數字小游戲產生一個隨機數randsrandRAND_MAX時間戳time() 示例 …

ShenNiusModularity項目源碼學習(8:數據庫操作)

ShenNiusModularity項目使用SqlSugar操作數據庫。在ShenNius.Repository項目中定義了ServiceCollectionExtensions.AddSqlsugarSetup函數注冊SqlSugar服務&#xff0c;并在ShenNius.Admin.API項目的ShenniusAdminApiModule.OnConfigureServices函數中調用&#xff0c;SqlSugar所…

MATLAB圖像處理:圖像特征概念及提取方法HOG、SIFT

圖像特征是計算機視覺中用于描述圖像內容的關鍵信息&#xff0c;其提取質量直接影響后續的目標檢測、分類和匹配等任務性能。本文將系統解析 全局與局部特征的核心概念&#xff0c;深入講解 HOG&#xff08;方向梯度直方圖&#xff09;與SIFT&#xff08;尺度不變特征變換&…

java枚舉類型的查找

AllArgsConstructor Getter public enum FileFilterRangeEnum {FILE_NAME("文件名稱","fileName"),FILE_CONTENT("文件內容","fileContent");private final String text;private final String value;// 根據傳入的字符串值查找對應的枚…

小白win10安裝并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路徑最好都是全英文 win10安裝并配置yt-dlp 一、下載1.下載yt-dlp2. fffmpeg下載 二、配置環境三、cmd操作四、yt-dlp下視頻操作 一、下載 1.下載yt-dlp yt-dlp地址 找到win的壓縮包點下載&#xff0c;并解壓 2. fffmpeg下載 ffmpeg官方下載 …

【技術解析】MultiPatchFormer:多尺度時間序列預測的全新突破

今天給我大家帶來一篇最新的時間序列預測論文——MultiPatchFormer。這篇論文提出了一種基于Transformer的創新模型&#xff0c;旨在解決時間序列預測中的關鍵挑戰&#xff0c;特別是在處理多尺度時間依賴性和復雜通道間相關性時的難題。MultiPatchFormer通過引入一維卷積技術&…

145,【5】 buuctf web [GWCTF 2019]mypassword

進入靶場 修改了url后才到了注冊頁面 注測后再登錄 查看源碼 都點進去看看 有個反饋頁面 再查看源碼 又有收獲 // 檢查$feedback是否為數組 if (is_array($feedback)) {// 如果是數組&#xff0c;彈出提示框提示反饋不合法echo "<script>alert(反饋不合法);<…

CTF-WEB: 利用iframe標簽利用xss,waf過濾后再轉換漏洞-- N1ctf Junior display

核心邏輯 // 獲取 URL 查詢參數的值 function getQueryParam(param) { // 使用 URLSearchParams 從 URL 查詢字符串中提取參數 const urlParams new URLSearchParams(window.location.search); // 返回查詢參數的值 return urlParams.get(param); } // 使用 DOMPuri…

晶閘管主要參數分析與損耗計算

1. 主要參數 斷態正向可重復峰值電壓 :是晶閘管在不損壞的情況下能夠承受的正向最大阻斷電壓。斷態正向不可重復峰值電壓 :是晶閘管只有一次可以超過的正向最大阻斷電壓,一旦晶閘管超過此值就會損壞,一般情況下 反向可重復峰值電壓 :是指晶閘管在不損壞的情況下能夠承受的…

el-select 設置寬度 沒效果

想實現下面的效果&#xff0c;一行兩個&#xff0c;充滿el-col12 然后設置了 width100%,當時一直沒有效果 解決原因&#xff1a; el-form 添加了 inline 所以刪除inline屬性 即可

Python創建FastApi項目模板

1. 項目結構規范 myproject/ ├── app/ │ ├── core/ # 核心配置 │ │ ├── config.py # 環境配置 │ │ └── security.py # 安全配置 │ ├── routers/ # 路由模塊 │ │ └── users.py # 用戶路由 │ ├…

面試完整回答:SQL 分頁查詢中 limit 500000,10和 limit 10 速度一樣快嗎?

首先&#xff1a;在 SQL 分頁查詢中&#xff0c;LIMIT 500000, 10 和 LIMIT 10 的速度不會一樣快&#xff0c;以下是原因和優化建議&#xff1a; 性能差異的原因 LIMIT 10&#xff1a; 只需要掃描前 10 條記錄&#xff0c;然后返回結果。 性能非常高&#xff0c;因為數據庫只…

一款利器提升 StarRocks 表結構設計效率

CloudDM 個人版是一款數據庫數據管理客戶端工具&#xff0c;支持 StarRocks 可視化建表&#xff0c;創建表時可選擇分桶、配置數據模型。目前版本持續更新&#xff0c;在修改 StarRocks 表結構方面進一步優化&#xff0c;大幅提升 StarRocks 表結構設計效率。當前 CloudDM 個人…

數量5 - 平面圖形、立體幾何

目錄 一、平面幾何問題1.三角形2.其他圖形二、立體幾何與特殊幾何1.表面積2.體積3.等比放縮(簡單)4.幾何最值(簡單)5.最短路徑一、平面幾何問題 平面圖形: 立體圖形: 1.三角形 特殊直角

CAS單點登錄(第7版)7.授權

如有疑問&#xff0c;請看視頻&#xff1a;CAS單點登錄&#xff08;第7版&#xff09; 授權 概述 授權和訪問管理 可以使用以下策略實施授權策略以保護 CAS 中的應用程序和依賴方。 服務訪問策略 服務訪問策略允許您定義授權和訪問策略&#xff0c;以控制對向 CAS 注冊的…

53倍性能提升!TiDB 全局索引如何優化分區表查詢?

作者&#xff1a; Defined2014 原文來源&#xff1a; https://tidb.net/blog/7077577f 什么是 TiDB 全局索引 在 TiDB 中&#xff0c;全局索引是一種定義在分區表上的索引類型&#xff0c;它允許索引分區與表分區之間建立一對多的映射關系&#xff0c;即一個索引分區可以對…

排序(Sortable)

排序&#xff08;Sortable&#xff09; 引言 在計算機科學和數據管理領域&#xff0c;排序算法是一項基本且重要的技能。排序算法能夠將一組無序的數據轉換為有序的數據&#xff0c;從而便于后續的數據處理和分析。本文將深入探討排序算法的基本概念、常用排序方法、以及它們…

紫光展銳蜂窩物聯網芯片V8850榮獲國密一級安全認證

近日&#xff0c;紫光展銳蜂窩物聯網芯片V8850榮獲國密一級認證&#xff0c;標志著展銳V8850在安全能力方面獲得權威認可&#xff0c;位居行業領先水平。這是紫光展銳繼短距物聯網芯片V5663在2020獲得ARM PSA Level 2認證&#xff0c;蜂窩物聯網芯片V8811在2021年獲得ARM PSA L…

I.MX6ull-I2C

一,I2C總線介紹 I2C(Inter-Integrated Circuit 集成電路)總線是Philips公司在八十年代初推出的一種串行、半雙工的總 線&#xff0c;主要用于近距離、低速的芯片之間的通信&#xff1b;I2C總線有兩根雙向的信號線&#xff0c;一根數據線SDA用于收 發數據&#xff0c;一根時鐘線…

書籍推薦:《書法課》林曦

記得樊登老師說過&#xff0c;如果你想了解一個事物&#xff0c;就去讀5本相關的書&#xff0c;你會比大部分人都更了解它。這是我讀的第4本和“書法”有關的書&#xff0c;作為一個零基礎的成年人&#xff0c;林曦這本《書法課》非常值得一讀。&#xff08;無論你是否寫字&…