題目連結:
題目意譯:
一個字串中的一個子字串為一個連續(非空)之字元序列。
一個母音子字串為只由母音('a' 、 'e' 、 'i' 、 'o' 和 'u')組成且五種母音都有出現於其中。
給定一字串 word,回傳 word 中的母音子字串之數量。
限制:
1 ≦ word.length ≦ 100
word 只由小寫英文字母組成。
範例測資:
範例 1:
輸入: word = "aeiouu"
輸出: 2
解釋: 母音子字串如下(以底線標注):
- "aeiouu"
- "aeiouu"
範例 2:
輸入: word = "unicornarihan"
輸出: 0
解釋: 5 種母音並無全數出現,所以沒有母音子字串。
範例 3:
輸入: word = "cuaieuouac"
輸出: 7
解釋: 母音子字串如下(以底線標注):
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
- "cuaieuouac"
解題思維:
直接窮舉並檢查每一個子字串固然是可行的,不過時間複雜度會是 O(n ^ 3),其中 n 為字串 word 之長度。
可以看到當我們知道 s[i] ~ s[j](i ≦ j)不是只由母音組成時,則其往後的子字串 s[i] ~ s[k](j < k)也就不需要檢查了,因為其也必不只由母音組成。
因此我們可以改成窮舉子字串的開頭位置,然後往右直到碰到不是母音的字元或是字串結尾為止(然後只需幾查是否五種母音都有出現)。因此現在時間複雜度降至 O(n ^ 2)。
但是我們可以做得更好:
掃過字串 word,過程中記錄每種母音最後出現的位置(索引值最大的)以及最近一次非母音(即子音)的出現位置 C(所有出現位置一開始都設為 -1,代表都還尚未出現過)。
當 word[i] 是一個子音時,我們更新最近一次子音出現位置 C = i;如果是母音的話,則更新對應母音種類的出現位置,並且我們掃過所有種類的母音找到其中出現位置最前面的(假設其位置為 X)。此時,如果 X < C 的話,則代表目前這個包含五種母音的子字串 word[X] ~ word[i] 之間參雜了一些子音,所以其不是母音子字串;反之,如果 X ≧ C,則
word[C + 1] ~ word[i]、
word[C + 2] ~ word[i]、
……
word[X] ~ word[i]
這 X - C 個子字串皆是母音子字串。
因此如此一來我們便變得有點類似第二個方式(窮舉開頭),只不過這次是窮舉所有子字串的結尾。而這個方式的時間複雜度為 O(n)。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。