问题描述 链接到标题

1156. 单字符重复子串的最大长度 (Medium) 如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字 符串。

给你一个字符串 text,你只能交换其中两个字符一次或者什么都 不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度 。

示例 1:

输入:text = "ababa"
输出:3

示例 2:

输入:text = "aaabaaa"
输出:6

示例 3:

输入:text = "aaabbaaa"
输出:4

示例 4:

输入:text = "aaaaa"
输出:5

示例 5:

输入:text = "abcdef"
输出:1

提示:

  • 1 <= text.length <= 20000
  • text 仅由小写英文字母组成。

解题思路 链接到标题

可以利用双指针解决,我们先用数组 $cnt$ 统计 $text$ 中每个字符的出现的次数。

然后我们定一个三个指针,分别为 $i$,$j$,$k$。初始时都为 $0$,然后我们让 $j$ 右移,直到 $text[j] \neq text[i]$,然后令 $k = j + 1$,再右移 $k$,直到 $text[k] \neq text[i]$,这里可以统计一次结果,$res = \max(res, \min(k - i, cnt[text[i]]))$,然后令 $i = j$,重复以上步骤直到 $i >= text.size()$。

代码 链接到标题

class Solution {
  public:
    int maxRepOpt1(string text) {
        int n = text.size();
        vector<int> prefix(26);
        for (int i = 1; i <= n; ++i) {
            int c = text[i - 1] - 'a';
            for (int j = 0; j < 26; ++j) {
                if (j == c) {
                    prefix[j] = prefix[j] + 1;
                } 
            }
        }
        int res = 0;
        int i = 0, j = 0, k = 0;
        while (i < n) {
        	while (j < n && text[j] == text[i]) {
        		++j;
        	} 
        	k = j + 1;
        	while (k < n && text[k] == text[i]) {
        		++k;
        	}
        	res = max(res, min(k - i, prefix[text[i] - 'a']));
        	i = j;
        }
        return res;
    }
};