451 字
2 分钟
2730. 找到最长的半重复子字符串

2730. 找到最长的半重复子字符串#

题目描述#

给你一个下标从 0 开始的字符串 s,只包含数字字符。如果一个字符串 t 中至多有一对相邻字符是相等的,则称 t 是半重复的。返回 s 中最长半重复子字符串的长度。

核心思想#

不定长滑动窗口,维护窗口内相邻相同字符对数 cnt_dup。

窗口合法的充要条件是 cnt_dup ≤ 1。

状态转移:

  • 右端点 right 进入窗口:若 s[right] == s[right-1],则 cnt_dup += 1(新增一对相邻相同)
  • 左端点 left 离开窗口:若 s[left] == s[left+1],则 cnt_dup -= 1(移除一对相邻相同)

当 cnt_dup > 1 时,不断右移 left 直到 cnt_dup ≤ 1。

算法步骤#

  1. 初始化 left = 0, cnt_dup = 0, ans = 0
  2. 遍历 right 从 0 到 n-1:
    • 若 right > 0 且 s[right] == s[right-1],cnt_dup += 1
    • 当 cnt_dup > 1 时:
      • 若 s[left] == s[left+1],cnt_dup -= 1
      • left += 1
    • 更新 ans = max(ans, right - left + 1)
  3. 返回 ans

逐步举例#

以 s = "1111" 为例,n = 4:

rights[right]s[right]==s[right-1]?cnt_dup收缩过程leftans
0’1’—0—01
1’1’是1—02
2’1’是2s[0]==s[1]→cnt=1,l=112
3’1’是2s[1]==s[2]→cnt=1,l=222

最终 ans = 2(最长半重复子串为 "11")。

复杂度分析#

  • 时间复杂度:O(n)。left 和 right 各遍历一次,每个元素最多被访问两次。
  • 空间复杂度:O(1)。仅用常数个变量。

参考#

代码实现#

class Solution:
def longestSemiRepetitiveSubstring(self, s: str) -> int:
ans = left = cnt = 0
for right in range(len(s)):
if right > 0 and s[right] == s[right - 1]:
cnt += 1
while cnt > 1:
if s[left] == s[left + 1]:
cnt -= 1
left += 1
ans = max(ans, right - left + 1)
return ans
import sys
sys.path.insert(0, "/workspace/projects/source/coding/sliding-window-two-pointers/02-variable-sliding-window/2730-semi-repetitive")
from solution import Solution
import unittest
class TestSemiRepetitive(unittest.TestCase):
def setUp(self):
self.solution = Solution()
def test_example1(self):
self.assertEqual(self.solution.longestSemiRepetitiveSubstring("52233"), 4)
def test_example2(self):
self.assertEqual(self.solution.longestSemiRepetitiveSubstring("5494"), 4)
def test_example3(self):
self.assertEqual(self.solution.longestSemiRepetitiveSubstring("1111111"), 2)
def test_single(self):
self.assertEqual(self.solution.longestSemiRepetitiveSubstring("1"), 1)
def test_no_repeat(self):
self.assertEqual(self.solution.longestSemiRepetitiveSubstring("12345"), 5)
if __name__ == "__main__":
unittest.main()
2730. 找到最长的半重复子字符串
https://h1s97x.github.io/posts/coding/coding-2730-semi-repetitive/
作者
H1S97X
发布于
2026-08-18
许可协议
CC BY-NC-SA 4.0
随机文章