Java實現 LeetCode 828 統計子串中的唯一字符(暴力+轉數組)

828. 統計子串中的唯一字符

我們定義了一個函數 countUniqueChars(s) 來統計字符串 s 中的唯一字符,並返回唯一字符的個數。

例如:s = “LEETCODE” ,則其中 “L”, “T”,“C”,“O”,“D” 都是唯一字符,因爲它們只出現一次,所以 countUniqueChars(s) = 5 。

本題將會給你一個字符串 s ,我們需要返回 countUniqueChars(t) 的總和,其中 t 是 s 的子字符串。注意,某些子字符串可能是重複的,但你統計時也必須算上這些重複的子字符串(也就是說,你必須統計 s 的所有子字符串中的唯一字符)。

由於答案可能非常大,請將結果 mod 10 ^ 9 + 7 後再返回。

示例 1:

輸入: “ABC”
輸出: 10
解釋: 所有可能的子串爲:“A”,“B”,“C”,“AB”,“BC” 和 “ABC”。
其中,每一個子串都由獨特字符構成。
所以其長度總和爲:1 + 1 + 1 + 2 + 2 + 3 = 10
示例 2:

輸入: “ABA”
輸出: 8
解釋: 除了 countUniqueChars(“ABA”) = 1 之外,其餘與示例 1 相同。
示例 3:

輸入:s = “LEETCODE”
輸出:92

提示:

0 <= s.length <= 10^4
s 只包含大寫英文字符

class Solution {
    /*
    大佬的解釋(比官方的解釋🐂🍺)
    對每一個字符i,向前找到相同的字符j,向後找到相同的字符k。當前字符對最終結果的貢獻是:(i-j)*(k-i)。

這相當於兩種方案的拼接:在字符串A(j到i)當中,字符i貢獻的次數是(i-j)次。在字符串B(k-i)當中,字符i貢獻的次數是(k-i)。那麼當兩者拼接的時候,字符i對子串(j到k)的貢獻就是兩種方案的乘積(符合乘法公式)。
    */
      public int uniqueLetterString(String s) {
        char[] cs = s.toCharArray();
        int size = cs.length;
        int[][] pos = new int[26][2];
        for (int i = 0; i < 26; i++) {
            pos[i][0] = pos[i][1] = -1;
        }
        long ans = 0;

        for (int i = 0; i < size; i++) {
            int c = cs[i] - 'A';
            int[] curpos = pos[c];
            if ( curpos[0] != -1 || curpos[1] != -1 ) {
                ans += (i-curpos[1]) * (curpos[1]-curpos[0]);
            }
            curpos[0] = curpos[1];
            curpos[1] = i;
        }

        for (int i = 0; i < 26; i++) {
            int[] curpos = pos[i];
            if (curpos[0] != -1 || curpos[1] != -1) {
                ans += (size-curpos[1]) * (curpos[1]-curpos[0]);
            }
        }

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