如果 same}>1,则不断移动左指针 left 直到 s[\textit{left}]=s[\textit{left}-1],此时将一对相同的字符移到窗口之外。然后将 same 置为 1。
然后统计子串长度 right}-\textit{left}+1 的最大值。
[sol-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: deflongestSemiRepetitiveSubstring(self, s: str) -> int: ans, left, same = 1, 0, 0 for right inrange(1, len(s)): same += s[right] == s[right - 1] if same > 1: left += 1 while s[left] != s[left - 1]: left += 1 same = 1 ans = max(ans, right - left + 1) return ans
[sol-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { publicintlongestSemiRepetitiveSubstring(String S) { vars= S.toCharArray(); intans=1, left = 0, same = 0, n = s.length; for (intright=1; right < n; right++) { if (s[right] == s[right - 1] && ++same > 1) { for (left++; s[left] != s[left - 1]; left++); same = 1; } ans = Math.max(ans, right - left + 1); } return ans; } }
[sol-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: intlongestSemiRepetitiveSubstring(string s){ int ans = 1, left = 0, same = 0, n = s.length(); for (int right = 1; right < n; right++) { if (s[right] == s[right - 1] && ++same > 1) { for (left++; s[left] != s[left - 1]; left++); same = 1; } ans = max(ans, right - left + 1); } return ans; } };
[sol-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funclongestSemiRepetitiveSubstring(s string)int { ans, left, same := 1, 0, 0 for right := 1; right < len(s); right++ { if s[right] == s[right-1] { same++ if same > 1 { left++ for s[left] != s[left-1] { left++ } same = 1 } } ans = max(ans, right-left+1) } return ans }
funcmax(a, b int)int { if b > a { return b }; return a }
复杂度分析
时间复杂度:\mathcal{O}(n),其中 n 为 s 的长度。注意 left 只会增加不会减少,所以二重循环的时间复杂度为 \mathcal{O}(n)。