LeetCode.893-特殊相等字符串組(Groups of Special-Equivalent Strings)

這是悅樂書的第344次更新,第368篇原創

01 看題和準備

今天介紹的是LeetCode算法題中Easy級別的第209題(順位題號是893)。
You are given an array A of strings.

Two strings S and T are special-equivalent if after any number of moves, S == T.

A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with S[j].

Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any string not in S is not special-equivalent with any string in S.

Return the number of groups of special-equivalent strings from A.

給定一個字符串數組A。

如果在任意數量的移動之後,兩個字符串S和T是特殊相等的,S == T

移動是指選擇兩個索引i和j,其中i%2 == j%2,並且用S[j]交換S[i]

現在,S是一個特殊相等字符串組,是A的非空子集,使得不存在於S中(但存在於A中)的任意字符串與S中的任何字符串不是特殊相等的。

返回A中特殊相等字符串組的數量。例如:

輸入:[“a”,“b”,“c”,“a”,“c”,“c”]
輸出:3
說明:3組[“a”,“a”],[“b”],[“c”,“c”,“c”]

輸入:[“aa”,“bb”,“ab”,“ba”]
輸出:4
說明:4組[“aa”],[“bb”],[“ab”],[“ba”]

輸入:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
輸出:3
說明:3組[“abc”,“cba”],[“acb”,“bca”],[“bac”,“cab”]

輸入:[“abcd”,“cdab”,“adcb”,“cbad”]
輸出:1
說明:1組[“abcd”,“cdab”,“adcb”,“cbad”]

注意

  • 1 <= A.length <= 1000

  • 1 <= A [i] .length <= 20

  • 所有A [i]具有相同的長度。

  • 所有A [i]僅包含小寫字母。

02 理解題意

起初看這道題的題目描述看的是一臉懵逼,不知道它要表達的是什麼意思,更不談如何解題了。

只能硬着頭皮看了,已經記不得看了多少遍了,結合它給的四個例子,終於是明白了它想要表達的意思,上面的中文描述是我在谷歌翻譯的基礎上做了潤色的,方便理解,不信邪的人可以直接看英文描述,可以看到你懷疑人生!

題目說兩個字符串S和J可以任意交換字符,但是有個前提i%2 == j%2,也就是說S的奇數位只能和奇數位換,S的偶數位只能和偶數位換,J的交換同理,換完之後要是S和J相等,就是特殊相等。

現在又有個特殊相等字符串組的概念,就是由那些特殊相等字符串組成的小幫派,每個小幫派裏面的字符串,都符合上面的轉換規則.問A中有多少個這樣的小幫派?

結合例四來講,很快你就會明白題目究竟是個神馬意思了。

第四個例子中,A = [“abcd”,“cdab”,“adcb”,“cbad”],最後輸出是特殊相等字符串組的數量爲1,我們來一起看看這個1是怎麼算出來的。

先對"abcd"轉換一把,'a''c'可以互換,'b''d'可以互換,題目既然說了是任意互換,也就是說不論先後順序,那我們就統一按照從小到大的順序來,轉換完之後就變成"ac" + "bd"="acbd"

按照這樣的邏輯,對"cdab""adcb""cbad"進行轉換後,都變成了"acbd",所以最後只存在1個幫派了,就是"acbd"

03 第一種解法

在處理每個單獨的字符串時,利用一個26位長度的int數組,記錄每個字符出現的次數,對奇數位、偶數維分開處理,然後將兩數組轉成一個新的字符串拼接在一起,存入HashSet中,最後特殊相等字符串組的數量就是HashSetsize了。

public int numSpecialEquivGroups(String[] A) {
    Set<String> set = new HashSet<String>();
    for (String str : A) {
        int[] odd = new int[26];
        int[] even = new int[26];
        for (int i=0; i<str.length(); i++) {
            if (i%2 == 0) {
                even[str.charAt(i)-'a']++;
            } else {
                odd[str.charAt(i)-'a']++;
            }
        }
        String newStr = Arrays.toString(odd)+Arrays.toString(even);
        set.add(newStr);
    }
    return set.size();
}


04 第二種解法

我們可以對上面的解法再優化下,只用一個int數組,但是長度變爲52,前半部分存偶數位,後半部分村奇數位,最後再轉成字符串,存入HashSet中,最後特殊相等字符串組的數量就是HashSetsize了。

public int numSpecialEquivGroups2(String[] A) {
    Set<String> set = new HashSet<String>();
    for (String str : A) {
        int[] count = new int[52];
        for (int i=0; i<str.length(); i++) {
            count[str.charAt(i)-'a'+26*(i%2)]++;
        }
        set.add(Arrays.toString(count));
    }
    return set.size();
}


05 小結

算法專題目前已連續日更超過六個月,算法題文章212+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章