2018-05-01 15:13:08
並查集是乙個時空複雜度非常優越的資料結構,並且通過優化後其複雜度為。
並查集的優化主要有兩個方面:
路徑壓縮:
按rank合併:
public class unionfindset問題描述:}public int find(int i)
public boolean union(int i, int j)
return true;}}
問題求解:
樹形下的無向圖判斷環路問題,圖的描述方式是採用邊集。
並查集本身就是樹形結構,而樹是乙個無向圖,具體來說,樹是乙個無環的連通圖,所以本題可以直接使用並查集來進行求解。
public int findredundantconnection(int edges)2019.04.21}return res;
}
public int findredundantconnection(int edges)問題描述:}return null;
}private int find(int parent, int i)
return parent[i];
}private boolean union(int parent, int i, int j)
問題求解:
class solution問題描述:問題求解:這裡有乙個o(n)的做法, 一次考慮兩個凳子,假設他們不為夫婦,為了讓這兩個位置坐的恰好是一對夫婦,那麼我們就需要調整其中乙個人的位置,如此調整直到所有的夫婦相鄰,交換的次數就是答案。下面給出證明。}for (int i = 0; i < ufs.parent.length; i++)
if (ufs.parent[i] == i) res++;
return res;
}}class unionfindset
}public int find(int i)
public boolean union(int i, int j)
return true;}}
將給定的row抽象成乙個n個頂點的無向圖(可能包含重邊),例如:
(_ _) (_ _) ... (_ _)vi和vj之間存在邊當且僅當vi和vj中存在一對夫婦,例如vi = (0,2),vj = (1, 4)存在一對夫婦(0, 1),而vi = (0, 2),vj = (1, 3)之間則存在兩對夫婦(0, 1)(2, 3),此vi和vj存在重邊。(v1 ) (v2 ) ... (vn )
考慮row陣列形成的無向圖,可以肯定要麼是孤立的單個節點,要麼是多個孤立的圈,例如row = [0, 1]是乙個孤立的點、row = [0, 2, 1, 3]則包含乙個圈v1, v2、row = [0, 3, 4, 1, 2, 5, 6, 8, 7, 9],包含兩個孤立的圈v1, v2, v3和v4, v5。
對於乙個圈來說,假設他有n個節點,那麼至少需要n-1次交換即可讓每個夫婦相鄰。有了這個結論,假定row陣列有n個點,m個孤立的圈,那麼至少需要n-m次交換即可。
public int minswapscouples(int row)問題描述:return n - cnt;
}private int find(int parent, int i)
return parent[i];
}private boolean union(int parent, int i, int j)
問題求解:
這個問題可以轉化為求圖中連通數的問題,也就是經典的陸地數量問題。對於x | y相等的兩個石頭我們需要建立他們之間的聯絡。
經典的連通子樹問題可以使用dfs進行求解,從dfs的演算法過程我們可以看到其實是一棵以起始點為root的樹,因此,在這次dfs中我們總可以從葉子節點開始選取,知道最後只剩下root節點。
最終的答案就是所有的stones的數目 - 連通塊的數目。
這裡並不打算使用dfs來進行求解,將使用ufs來進行求解。
使用並查集並不需要那麼形式化的專門使用乙個類來進行表徵,這就是乙個簡單的資料結構,只需要在使用前進行定義就好了,另外,由於parent的數目範圍不確定,所以在很多時候使用陣列並不是乙個合適的選擇,使用hash表更能方便我們解決問題,本題就是使用hash表來進行的並查集的實現。
public int removestones(int stones)問題描述:問題求解:主要問題就是怎麼將字串的輸入進行轉化,這裡採用的轉化方式是將每個cell看成4個區域,0-3。根據不同的情況可以將各個區域進行合併,這樣本題就又變成了並查集問題。int cnt = 0;
for (int key : parent.keyset())
return n - cnt;
}private int find(mapparent, int i)
return parent.get(i);
}private boolean union(mapparent, int i, int j)
int n;public int regionsbyslashes(string grid)
if (grid[i].charat(j) != '\\') }}
return size;
}private int find(int parent, int i)
return parent[i];
}private boolean union(int parent, int i, int j)
private int getidx(int i, int j, int num)
並查集及優化 C
include include include include using namespace std 查詢快,但是合併差 class unionfind1 int find int p bool isconnected int p,int q void union int p,int q 基於2的...
並查集的實現及優化
並查集是一種用於在森林中判斷子圖數量及點的歸屬的資料結構,由於其特殊的路徑壓縮操作,使得這一過程可以異常地快。並查集主要由乙個pre陣列以及兩個函式組成 find函式和join函式。pre陣列表示每一節點的前驅,最終已完成的並查集,每乙個子圖的所有點只有乙個前驅 這也是其高效的原因 而初始化的並查集...
並查集的分析及應用
昨天看了幾篇有關並查集的 對理解並查集很有幫助,在這裡寫篇部落格來記錄下自己對並查集的簡單理解,以及並查集的簡單運用。並查集的分析 並查集的概念主要是處理集合問題 或可抽象成集合概念的問題 首先數學上的集合概念做個初步的分析 首先,我們從數學的角度給出等價關係和等價類的定義 定義1 如果集合s中的關...