LeetCode 1156.单字符重复子串的最大长度

发布于:2025-07-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。

给你一个字符串 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 仅由小写英文字母组成。

滑动窗口,保证窗口内最多有两种字符,有两种字符时,保证一种字符的数量为1。
当窗口内有两种字符时,如果窗口大小为winSize,其中一种字符a的数量为1,另一种字符b的数量就是n-1
如果数量为n-1的字符a在窗口外还有字符,则整个窗口都是合法的子串,因为可以把窗口外的一个字符a和窗口内的字符b交换位置;否则窗口内合法的子串长度就是n-1,因为可以自由交换窗口内的字符b到窗口两端点。
找出最大的窗口内合法子串长度即可。

class Solution {
public:
    int maxRepOpt1(string text) {
        int cnt[26];
        for (char c : text) {
            ++cnt[c - 'a'];
        }

        int left = 0;
        int ans = 0;
        map<char, int> cur;
        for (int i = 0; i < text.size(); ++i) {
            ++cur[text[i]];

            while (cur.size() == 3 || 
                cur.size() == 2 &&
                cur.rbegin()->second >= 2 && 
                cur.begin()->second >= 2) {

                if (--cur[text[left]] == 0) {
                    cur.erase(text[left]);
                }
                ++left;
            }

            char more = cur.rbegin()->first;
            if (cur.begin()->second > cur.rbegin()->second) {
                more = cur.begin()->first;
            }
            int len = min(cnt[more - 'a'], i - left + 1);
            ans = max(ans, len);
        }

        return ans;
    }
};

如果text的长度为n,其中的字符种类数为m,则此算法时间复杂度为O(n),空间复杂度为O(m),本题m为26。


网站公告

今日签到

点亮在社区的每一天
去签到