給你一個下標從?0?開始的字符串?s
?,這個字符串只包含?0
?到?9
?的數字字符。
如果一個字符串?t
?中至多有一對相鄰字符是相等的,那么稱這個字符串?t
?是?半重復的?。例如,0010
?、002020
?、0123
?、2002
?和?54944
?是半重復字符串,而?00101022
?和?1101234883
?不是。
請你返回?s
?中最長?半重復?子字符串的長度。
一個?子字符串?是一個字符串中一段連續?非空?的字符。
示例 1:
輸入:s = "52233" 輸出:4 解釋:最長半重復子字符串是 "5223" ,子字符串從 i = 0 開始,在 j = 3 處結束。
示例 2:
輸入:s = "5494" 輸出:4 解釋:s 就是一個半重復字符串,所以答案為 4 。
示例 3:
輸入:s = "1111111" 輸出:2 解釋:最長半重復子字符串是 "11" ,子字符串從 i = 0 開始,在 j = 1 處結束。
提示:
1 <= s.length <= 50
'0' <= s[i] <= '9'
?思路:用當前遍歷到的元素減去上一個出現過兩個重復元素的右端點,然后迭代找到最大值
int longestSemiRepetitiveSubstring(string s) { // 函數名:找到最長的半重復子字符串,參數為一個字符串sint preLeft = 0, left = 0, ans = 1; // preLeft表示前一個重復字符的左邊界,left表示當前重復字符的左邊界,ans表示最長半重復子字符串的長度for (int i = 1; i < s.size(); ++i) { // 遍歷字符串s的字符if (s[i] == s[i - 1]) { // 如果當前字符和前一個字符相同preLeft = left; // 更新前一個重復字符的左邊界為當前重復字符的左邊界left = i; // 更新當前重復字符的左邊界為當前字符的位置}ans = max(ans, i - preLeft + 1); // 更新最長半重復子字符串的長度}return ans; // 返回最長半重復子字符串的長度
}
?所謂半重復子字符串是指字符串中某個子串,其中相鄰的兩個字符相同,但不要求全部字符都相同。算法采用遍歷字符串的方式,通過維護兩個指針(preLeft和left)來記錄重復字符的位置,并動態更新最長半重復子字符串的長度。