leetcode 684. Redundant Connection | 684. 冗余连接(并查集)
生活随笔
收集整理的這篇文章主要介紹了
leetcode 684. Redundant Connection | 684. 冗余连接(并查集)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
https://leetcode.com/problems/redundant-connection/
題解
并查集問題
1)有若干個樣本a、b、c、d…類型假設是V
2)在并查集中一開始認為每個樣本都在單獨的集合里
3)用戶可以在任何時候調用如下兩個方法:
? boolean isSameSet(V x, V y) : 查詢樣本x和樣本y是否屬于一個集合
? void union(V x, V y) : 把x和y各自所在集合的所有樣本合并成一個集合
4)isSameSet和union方法的代價越低越好
并查集
1)每個節點都有一條往上指的指針
2)節點a往上找到的頭節點,叫做a所在集合的代表節點
3)查詢x和y是否屬于同一個集合,就是看看找到的代表節點是不是一個
4)把x和y各自所在集合的所有點合并成一個集合,只需要小集合的代表點掛在大集合的代表點的下方即可
并查集的優化
1)節點往上找代表點的過程,把沿途的鏈變成扁平的
2)小集合掛在大集合的下面
3)如果方法調用很頻繁,那么單次調用的代價為O(1),兩個方法都如此
并查集的應用
解決兩大塊區域的合并問題
常用在圖等領域中
本題題解
class Solution {public int[] findRedundantConnection(int[][] edges) {int N = 0;for (int[] pair : edges) {N = Math.max(N, Math.max(pair[0], pair[1]));}// union findint[] size = new int[N + 1]; // i所在的集合大小Arrays.fill(size, 1);int[] parent = new int[N + 1];for (int i = 0; i <= N; i++) {parent[i] = i;}for (int[] pair : edges) {int r0 = findRoot(parent, pair[0]);int r1 = findRoot(parent, pair[1]);if (r0 == r1) return pair;// 如果pair[0], pair[1]不在同一集合,則將小集合代表掛在大集合代表下方if (size[r0] > size[r1]) {parent[r1] = r0;} else {parent[r0] = r1;}size[r0] = size[r1] = size[r0] + size[r1];}return null;}// 從i開始一直往上,往上到不能再往上,代表節點,返回// 這個過程要做路徑壓縮public int findRoot(int[] parent, int i) {int cur = i;while (cur != parent[cur]) {cur = parent[cur];}while (i != parent[i]) {int next = parent[i];parent[i] = cur;i = next;}return cur;} }總結
以上是生活随笔為你收集整理的leetcode 684. Redundant Connection | 684. 冗余连接(并查集)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 678. Valid
- 下一篇: leetcode 130. Surrou