给你一个下标从 0 开始的字符串 s
,这个字符串只包含 0
到 9
的数字字符。
如果一个字符串 t
中至多有一对相邻字符是相等的,那么称这个字符串 t
是 半重复的 。例如,"0010"
、"002020"
、"0123"
、"2002"
和 "54944"
是半重复字符串,而 "00101022"
(相邻的相同数字对是 00 和 22)和 "1101234883"
(相邻的相同数字对是 11 和 88)不是半重复字符串。
请你返回 s
中最长 半重复 子字符串的长度。
示例 1:
输入:s = "52233"
输出:4
解释:
最长的半重复子字符串是 "5223"。整个字符串 "52233" 有两个相邻的相同数字对 22 和 33,但最多只能选取一个。
示例 2:
输入:s = "5494"
输出:4
解释:
s
是一个半重复字符串。
示例 3:
输入:s = "1111111"
输出:2
解释:
最长的半重复子字符串是 "11"。子字符串 "111" 有两个相邻的相同数字对,但最多允许选取一个。
想法:
看到最长子字符串可利用滑动窗口来解决,先定义重复数cnt=0,再移动右指针r,在r - l > 0 的情况下判断s[r]和s[r-1]是否相同,如果相同则cnt++,如果cnt>1就说明不符合题目条件,判断s[l]和s[l+1]是否相同,如果相同,cnt--,之后左指针右移,判断最长长度。
代码如下(非最优解):
int longestSemiRepetitiveSubstring(char * s){
int l = 0, r = -1, len = strlen(s), maxlen = 0, cnt = 0;
while(r < len - 1){
++r;
if(r - l > 0){
if(s[r] == s[r - 1]) cnt++;
while(cnt > 1){
if(s[l] == s[l + 1]) cnt--;
l++;
}
}
if(maxlen < r - l + 1) maxlen = r - l + 1;
}
return maxlen;
}