並查集的妙用 Leetcode 1202

2021-10-03 10:36:54 字數 2353 閱讀 1654

給你乙個字串 s,以及該字串中的一些「索引對」陣列 pairs,其中 

pairs[i] = [a, b] 表示字串中的兩個索引(編號從 0 開始)。

你可以 任意多次交換 在 pairs 中任意一對索引處的字元。

返回在經過若干次交換後,s 可以變成的按字典序最小的字串。

示例 1:

輸入:s = "dcab", pairs = [[0,3],[1,2]]

輸出:"bacd"

解釋:

交換 s[0] 和 s[3], s = "bcad"

交換 s[1] 和 s[2], s = "bacd"

示例 2:

輸入:s = "dcab", pairs = [[0,3],[1,2],[0,2]]

輸出:"abcd"

解釋:交換 s[0] 和 s[3], s = "bcad"

交換 s[0] 和 s[2], s = "acbd"

交換 s[1] 和 s[2], s = "abcd"

示例 3:

輸入:s = "cba", pairs = [[0,1],[1,2]]

輸出:"abc"

解釋:交換 s[0] 和 s[1], s = "bca"

交換 s[1] 和 s[2], s = "bac"

交換 s[0] 和 s[1], s = "abc"

1 <= s.length <= 10^5

0 <= pairs.length <= 10^5

0 <= pairs[i][0], pairs[i][1] < s.length

s 中只含有小寫英文本母

這個題的思路是很容易想到的,pairs把下標分成若干組,其中每一組內的下標,元素是可以以任意順序排列的。那麼只需要把這些下標分成若干組,在把每組內的下標對應的元素公升序排列,就可以得到答案了。很顯然,想要找到互相有聯絡的下標,就要用到並查集。第一次打出來的**如下:

class

solution

} vector<

bool

>

flags

(s.size()

,1);

int cur_union =-1

;for

(bool b =0;

; b =

0, cur_union =-1

)else

//當前已有聯盟}}

}if(!b)

sort

(str.

begin()

, str.

end())

;for

(int i =

0; i < str.

size()

;++i)

}return s;

}int

findunion

(int i, unordered_map<

int,

int>

& hash)

if(hash[i]

!= i)

return hash[i];}

};

這份**並不是很優秀的,主要有以下幾個問題:

· map和unordered_map的key在未插入的情況下,訪問這個key,會自動把key的value賦值為0,因此findunion函式要先判斷是否存在key;

· 所有下標分組後,對每個組的下標對應的元素進行排序的過程過於繁瑣

因此,**可以做以下改進。首先,用vector代替unordered_map,作為並查集;其次可以對分好組的下標對應的元素,用**所示的方法進行排序:

class

solution

for(

auto

& it : pairs)

} unordered_map<

int, vector<

int>

> mem;

//key是「盟主」, value是個向量,儲存「聯盟」的所有下標對應的字元

for(

int i =

0; i < n;

++i)

for(

auto

& it : mem)

string res;

for(

int i =

0; i < n;

++i)

return res;

}int

findunion

(int i)

return parent[i];}

vector<

int> parent;

};

初學並查集 並查集1

現在,我是用乙個初學者的眼光來寫並查集,此文最初寫於我學並查集的那天,後經過多次修改。1 並查集是什麼 並查集是乙個具有多個連通分支的圖,他擁有合併兩個連通分支,和查詢兩個元素是否位於同乙個連通分支的功能。2 並查集的簡單應用 並查集解決什麼問題 假如有一些點,你知道哪些點是直接相連的,但實際上間接...

並查集初學(1)

出處 github 並查集 union find sets 是一種非常精巧而實用的資料結構,它主要用於處理一些不相交集合的合併問題。一些常見的用途有求連通子圖 求最小生成樹的 kruskal 演算法和求最近公共祖先 least common ancestors,lca 等。使用並查集時,首先會存在一...

並查集 題1

問題描述 今天是ignatius的生日。他邀請很多朋友。現在是晚餐時間。ignatius想知道他至少需要多少張桌子。你必須注意到,並不是所有的朋友都認識對方,所有的朋友都不想留在陌生人身上。這個問題的乙個重要規則是,如果我告訴你a知道b,b知道c,這意味著a,b,c彼此認識,所以他們可以留在乙個表中...