前往
大廳
主題

LeetCode - 2272. Substring With Largest Variance 解題心得

Not In My Back Yard | 2023-09-11 12:00:25 | 巴幣 0 | 人氣 94

題目連結:


題目意譯:
一個字串的變異數為任兩種字元在字串中的出現次數的差值之可能的最大值。注意到這兩個字元可能一樣也可能不一樣。

給定一個由小寫英文字母組成的字串 s,回傳在 s 中所有子字串中最大的可能變異數。

一個子字串為一字串中一個連續字元序列。

限制:
1 ≦ s.length ≦ 10 ^ 4
s 由小寫英文字母組成。



範例測資:
範例 1:
輸入: s = "aababbb"
輸出: 3
解釋:
所有可能的變異數之值與其相對應的子字串為下列:
- 變異數為 0 的子字串 "a" 、 "aa" 、 "ab" 、 "abab" 、 "aababb" 、 "ba" 、 "b" 、 "bb" 和 "bbb"。
- 變異數為 1 的子字串 "aab" 、 "aba" 、 "abb" 、 "aabab" 、 "ababb" 、 "aababbb" 和 "bab"。
- 變異數為 2 的子字串 "aaba" 、 "ababbb" 、 "abbb" 和 "babb"。
- 變異數為 3 的子字串 "babbb"。
由於最大的變異數為 3,因此我們回傳它。

範例 2:
輸入: s = "abcde"
輸出: 0
解釋:
s 中沒有字母出現超過一次,因此每一個子字串的變異數為 0。


解題思維:
其實就是窮舉每一種可能的字母對(如 (a, b) 、 (a, c) 、 ……,而 (c, c) 這種不需要窮舉,因為其變異數是 0)。對於每一組字母對,可以利用類似括號匹配(如這題)的精神來找出對於該字母對出現次數相差最大的子字串。

而過程中我們會需要維護一個變數 balance 來代表現在的兩字母的出現次數之差值。而在一次掃過 s 中,我們需要先以其中一個字母作為扮演「左括號」的角色,而另一個字母則是「右括號」;而再另一次掃過 s 的過程中,兩字母將交換角色。

而每當遇到「左括號」時,則直接將 balance 加上 1。

而遇到「右括號」時,則先判斷當前 balance 之值是否 < 0,如果是的話則直接從這個「右括號」開始重算 balance,代表先前的結果數值太低了,就算後面有很多「左括號」,也不會使 balance 之值比現在重算來得大;而如果 balance 之值 ≧ 0 且我們是從某個「右括號」重算得來的,則捨棄掉開頭的「右括號」替換成現在看到的「右括號」;剩下的就是直接把 balance 減去 1,然後再檢查一次其值有沒有 < 0(如第一個情況,而實際上這兩者可以合併)。

然後過程中只要取 balance 最大之值(但是記得兩者都要有出現過才能算數)即可知道對於當前字母對出現次數相差最大可為何。



最後把所有字母對的結果取最大值即是所求最大變異數之值。




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

創作回應

更多創作