前往
大廳
主題

LeetCode - 2157. Groups of Strings 解題心得

Not In My Back Yard | 2022-09-09 12:00:12 | 巴幣 0 | 人氣 291

題目連結:


題目意譯:
你被給定一個索引值從 0 開始的字串陣列 words。每個字串只由小寫英文字母組成。在 words 中任一字串中沒有字母出現多於一次。

兩字串 s1 和 s2 是相連的,如果 s2 的字母集合可以從 s1 的字母集合經由以下操作之一得到:
在 s1 的字母集合中加入恰好一個字母。
從 s1 的字母集合中刪除恰好一個字母。
把 s1 的字母集合中恰好一個字母替換成任何一個字母,包含它自己。

陣列 words 可以分割成一個或多個非重疊的群組。一個字串被視為屬於某一群組,如果下列任何一個條件為真:
它至少與群組中的其中一個字串相連。
它為群組中唯一一個字串。

注意到 words 中的字串應分成若干的群體,使得任意字串屬於某個群體不會相連於另一個群體中的字串。可以證明這樣子的分組方式必定唯一。

回傳一個大小為 2 的陣列 ans,其中:
ans[0] 為最多可分割出來的群體之數目,且
ans[1] 為其中最大的群體之大小。

限制:
1 ≦ words.length ≦ 2 × 10 ^ 4
1 ≦ words[i].length ≦ 26
words[i] 只由小寫英文字母組成。
words[i] 中沒有字母出現多於一次。



範例測資:
範例 1:
輸入: words = ["a","b","ab","cde"]
輸出: [2,3]
解釋:
- words[0] 可以得到 words[1](藉由將 'a' 替換成 'b')以及 words[2](藉由加入 'b')。因此 words[0] 相連於 words[1] 以及 words[2]。
- words[1] 可以得到 words[0](藉由將 'b' 替換成 'a')以及 words[2](藉由加入 'a')。因此 words[1] 相連於 words[0] 以及 words[2]。
- words[2] 可以得到 words[0](藉由刪除 'b')以及 words[1](藉由刪除 'a')。因此 words[2] 相連於 words[0] 以及 words[1]。
- words[3] 不與 words 中任意其他字串相連。
因此,words 可以分成兩個群組 ["a","b","ab"] 和 ["cde"]。最大的群組之大小為 3。

範例 2:
輸入: words = ["a","ab","abc"]
輸出: [1,3]
解釋:
- words[0] 與 words[1] 相連。
- words[1] 與 words[0] 和 words[2] 相連。
- words[2] 與 words[1] 相連。
因此所有字串與彼此相連,它們應與彼此分到同一組。
因此,最大的群組之大小為 3。


解題思維:
首先,想辦法找到所有字串的相連關係。之後基本上就是套經典的併查集(Union-Find Set,參見這題的介紹)即可得到所有應分出來的群組(即「代表」的數量)以及最大群組之大小(即 rank 之大小)。


那要怎麼找到相連關係呢?
可以看到因為小寫英文字母只有 26 個,因此我們可以用一個 26 位元長的數字來表示一個 words 中的字串有哪些字母。因此接著我們就可以掃過這些位元(比起直接掃所有字母,這樣比較方便),然後試試看題目中的提及的三個操作:
1. 增加字母:即把一個「0」之位元變成「1」;
2. 刪除字母:即把一個「1」之位元變成「0」;
3. 替換字母:即把一個「1」之位元變成「0」,然後把現在是「0」的位元變為「1」。
對於字串中每種字母都做過一次對應的操作之後,利用雜湊表(Hash Table)來看改變後的位元狀態是否存在(代表有對應的字串存在),即表示這兩個(或以上,不過相同的字母集合可以忽略掉到只剩唯一一個)字串相連。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作