828. Count Unique Characters of All Substrings of a Given String
題目網址:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/
題意:定義一函數
countUniqueChars(s)返回 strings中只出現一次的 char 之個數。e.g.
s = "LEETCODE", 其中L、T、C、O、D皆只出現過一次, 因此countUniqueChars(s) = 5。今給一 string
s, 返回countUniqueChars(t)的總和, 其中t是s的 substring。注意:
- 有些 substring 是會重複的, 計算時也必須算上這些重複的 substring(也就是說, 統計
s所有 substring 中只出現一次的 char)。s僅由大寫英文所組成。

Solution 1:
想法:與其計算所有 substring 中的 unique char 個數, 不如計算單一 char 在哪些 substring 是 unique char, 最後做加總即為所求
- 考慮
s = XAXAXXAX並專注於使第二個A成為 unique char- 我們可以取
XA(XAXX)AX, 其中()中間的範圍就是符合條件的 substring 範圍- 因此, 能使第二個
A為 unique char 的總共有 6 種 substring
- 第二個
A以左(不含A)可取""、X這 2 種 substring- 第二個
A以右(不含A)可取""、X、XX這 3 種 substring- 總共有
A、AX、AXX和XA、XAX、XAXX這 6 種 substring- 若想求
idx = i的 char 為 unique char 的 substring 個數, 我們需要:
- 前一個跟
s[i]相同的 char 的 idxj- 後一個跟
s[i]相同的 char 的 idxk- substring 個數 =
(i - j) * (k - i)- 因此, 我們要紀錄相同的 char 所有出現的位置
- 特殊情況:當
s中和s[i]相同的 char 不滿 2 個時, 也就是s[i]找不到前一個相同的 char 或後一個相同的 char 時- 解決辦法:在每個 char 紀錄所有位置的開頭加上
1, 且結尾加上n, 這樣即便s中沒有任何跟s[i]相同的 char 也能計算 substring 個數 =(i + 1) * (n - i)
- e.g.
s = XA, 可得到A的idx = [-1, 1, 2]
A以左(不含A)可取""、X這 2 種 substringA以右(不含A)可取""這 1 種 substring(1 + 1) * (2 - 1) = 2, 總共有A、XA這 2 種 substring
class Solution { |
- time:$O(n)$ ➔ 遍歷
s - space:$O(n)$ ➔
idx紀錄s中每個元素出現的位置
Solution 2:
想法:利用 Sliding window, 概念同 Solution 1, 只是計算
idx = i之 substring 個數時, 只會用到前一個和後一個相同 char 的 idx, 故不需要一次紀錄所有相同 char 的位置
- 首先, 我們先將
last2idx每個 char 的前兩個位置初始化為1, -1(當前i作為第三個位置)
➔ 貢獻值公式:(第二個位置 - 第一個位置) * (i - 第二個位置)- 遍歷
s中每個 char, 此時計算前一個 char(第二個位置)的貢獻值, 並累加到res中- 假如當前 char 是首次出現, 因為前兩個 char 的出現位置都是
1, 相減後為0, 所以累加值還是0- 然後更新
last2idx中的值- 由於每次都是計算該 char 的前一個位置之貢獻值, 所以最後還需要一個 for loop 去計算每個 char 最後出現位置的貢獻值。由於最後一個 char 後面沒有相同 char 了, 故用
n來替代其後一個 idx
class Solution { |
- time:$O(n)$ ➔ 遍歷
s - space:$O(1)$ ➔ $O(26 \cdot 2)$, 因為
last2idx只需常數空間
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論