1156. 单字符重复子串的最大长度
难度:中等
时间:2023/06/03
如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。
给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度。
示例 1:
输入:text = "ababa"
输出:3
示例 2:
输入:text = "aaabaaa"
输出:6
示例 3:
输入:text = "aaabbaaa"
输出:4
示例 4:
输入:text = "aaaaa"
输出:5
示例 5:
输入:text = "abcdef"
输出:1
提示:
1 <= text.length <= 20000text仅由小写英文字母组成。
解题思路:
要求计算重复子串相关的题,优先想到双指针。这题可以使用一次遍历+双指针进行求解。
首先统计text字符串中每个单词出现的次数; 然后遍历数组,假设遍历到当前元素i的值为a,使用双指针计算i后连续的且与a相同的元素个数,若该个数小于a在text中出现的总次数,说明可以将一个a交换过来,从而得到更长的一段仅包含字符 a 的子串。交换后,交换过来的 a 可能会使得两段连续的 a 拼接在一起,拼接后连续 a 长度即为 a 的最长子串长度。 通过一次遍历后返回所有字符中最长子串长度最大的那一个。
class Solution:
def maxRepOpt1(self, text: str) -> int:
ans = 1
cnt = Counter(text)
for i in range(26):
ch = chr(ord('a') + i)
l, t, mid = 0, 0, 0
for r, x in enumerate(text):
if x != ch:
t += 1
if t == 1:
mid = r
if t < 2:
ans = max(ans, min(r - l + 1, cnt[ch]))
else:
t -= 1
l = mid + 1
mid = r
return ans
总结: 本题的难点是交换一个字符后可以继续搜索,所以大致有两种情况,一个是当前最长的相同字符串,另一个是当前的长度,跳过一个不同的,再加上下一个相同字符串。采取贪心的做法,第二种情况的长度肯定不小于第一种情况,所以,结果只取第二种情况的长度。用了一个新的指针k,去搜索第二个可能的字符串的长度。更新结果的时候,结果不会超过当前字符的总数量,这是最巧妙的地方,相当于贪心的去搜索可能的最长的长度,但有效的最大值只能是字符的数量。
用的是常规的滑动窗口,i 是起始位置,j 是下一个起始位置/第一个不同的字符的位置/当前连续相同字符串的下一个位置/字符串的末端的下一个位置。 本题的难点是交换一个字符后可以继续搜索,所以大致有两种情况,一个是当前最长的相同字符串,另一个是当前的长度,跳过一个不同的,再加上下一个相同字符串。采取贪心的做法,第二种情况的长度肯定不小于第一种情况,所以,结果只取第二种情况的长度。用了一个新的指针k,去搜索第二个可能的字符串的长度。更新结果的时候,结果不会超过当前字符的总数量,这是最巧妙的地方,相当于贪心的去搜索可能的最长的长度,但有效的最大值只能是字符的数量。