前往
大廳
主題

LeetCode - 1061. Lexicographically Smallest Equivalent String 解題心得

Not In My Back Yard | 2023-12-13 12:00:01 | 巴幣 100 | 人氣 80

題目連結:


題目意譯:
你被給定兩個相同長度的字串 s1 和 s2 以及另一字串 baseStr。

我們定義 s1[i] 和 s2[i] 為等價字元。

例如說,如果 s1 = "abc" 而 s2 = "cde",則我們有 'a' == 'c' 、 'b' == 'd' 以及 'c' == 'e' 之等價關係。

等價字元將遵循著一般其他的等價關係之規則:
反身性(Reflexivity): 'a' == 'a'。
對稱性(Symmetry): 'a' == 'b' 意味著 'b' == 'a'。
遞移性(Transitivity): 'a' == 'b' 且 'b' == 'c' 意味著 'a' == 'c'。

例如說,從 s1 = "abc" 且 s2 = "cde" 給定的等價關係可以得到 "acd" 和 "aab" 為 baseStr = "eed" 的等價字串。而 "aab" 是 baseStr 的等價字串中字典序最小者。

回傳藉由 s1 和 s2 得出的等價關係所能得到的 baseStr 之等價字串中的字典序最小者。

限制:
1 ≦ s1.length, s2.length, baseStr ≦ 1000
s1.length == s2.length
s1 、 s2 和 baseStr 由小寫英文字母組成。



範例測資:
範例 1:
輸入: s1 = "parker", s2 = "morris", baseStr = "parser"
輸出: "makkek"
解釋: 基於 s1 和 s2 的等價關係,我們可以把它們的字元圈成若干個群組如 [m,p] 、 [a,o] 、 [k,r,s] 、 [e,i]。
每一群之中的字元都彼此等價且以字典序排序。
所以答案為 "makkek"。

範例 2:
輸入: s1 = "hello", s2 = "world", baseStr = "hold"
輸出: "hdld"
解釋: 基於 s1 和 s2 的等價關係,我們可以把它們的字元圈成若干個群組如 [h,w] 、 [d,e,o] 、 [l,r]。
所以只有 baseStr 中的第二個字母 'o' 會被變成 'd',而答案為 "hdld"。

範例 3:
輸入: s1 = "leetcode", s2 = "programs", baseStr = "sourcecode"
輸出: "aauaaaaada"
解釋: 我們基於 s1 和 s2 的等價關係字元圈成若干個群組如 [a,o,e,r,s,c] 、 [l,p] 、 [g,t] 和 [d,m],因此在 baseStr 中除了 'u'和 'd' 之外的字母都將變成 'a',而答案為 "aauaaaaada"。


解題思維:
把範例測資中的「群組」想成是集合。而每一個集合中我們固定都會去找當中字典序的字母,所以看做是該集合的「代表」(Representative)。而題目敘述中提及的「遞移性」可以想做是兩個集合在「合併」。

因此我們可以使用併查集(Union-Find Set)來解決這些事情。參見這題對於併查集的介紹。

不過因為每一次合併時,「代表」固定會是去取字典序較小者而不是看集合大小。因此不會有按秩合併(Union-by-rank),但是路徑壓縮(Path Compression)依舊可以使用。所以時間複雜度不會是 O(n × α(n)),而是上述文章中最下面提及的那一串時間複雜度。



建立完這些集合之後(沒有出現在 s1 和 s2 中的字母預設為自己一個群組)。掃過一次 baseStr 的每個字元,並將每個字元變成對應集合中的「代表」即可得到所求。




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

創作回應

更多創作