找出出现至少三次的最长特殊子字符串 II(二分,字符串)

https://leetcode.cn/problems/find-longest-special-substring-that-occurs-thrice-ii/description/
给你一个仅由小写英文字母组成的字符串\(s\)

如果一个字符串仅由单一字符组成,那么它被称为 特殊 字符串。例如,字符串 "abc" 不是特殊字符串,而字符串 "ddd"、"zz" 和 "f" 是特殊字符串。

返回在\(s\)中出现 至少三次最长特殊子字符串 的长度,如果不存在出现至少三次的特殊子字符串,则返回 -1 。

子字符串 是字符串中的一个连续 非空 字符序列。
示例 1:
输入:s = "aaaa"
输出:2
解释:出现三次的最长特殊子字符串是 "aa" :子字符串 "aaaa"、"aaaa" 和 "aaaa"。
可以证明最大长度是 2 。

示例 2:
输入:s = "abcdef"
输出:-1
解释:不存在出现至少三次的特殊子字符串。因此返回 -1 。

示例 3:
输入:s = "abcaba"
输出:1
解释:出现三次的最长特殊子字符串是 "a" :子字符串 "abcaba"、"abcaba" 和 "abcaba"。
可以证明最大长度是 1 。
提示:
\(3 <= s.length <= 5 * 10^5\)
s 仅由小写英文字母组成。

首先先看好题目,他说的特殊子字符串必须得是重复的,还有一点就是这个答案一定是符合二分条件的,所以我们使用二分,对于judge函数:先求得mid,如果我们有连续的cnt个字符'a',那么他的贡献就是(cnt-mid+1),我们用一个数组储存上这个贡献,最后我们再判断一下即可

class Solution {
public:
    int judge(string s,int mid){
        int n=s.size();
        int cnt[30];
        for(int i=0;i<29;i++){
            cnt[i]=0;
        }
        s[n]='#';
        int tmp=1;
        for(int i=0;i<n;i++){
            if(s[i+1]!=s[i]){
                cnt[s[i]-'a']+=(tmp-mid+1)>0?(tmp-mid+1):0;
                tmp=1;
            }
            else{  
                tmp++;
            }
        }
        for(int i=0;i<26;i++){
            if(cnt[i]>=3){
                return true;
            }
        }
        return false;
    }
    int maximumLength(string s) {
        int n=s.size();
        int l=1,r=n,ans=-1;
        while(r>=l){
            int mid=(l+r)/2;
            if(judge(s,mid)){
                l=mid+1;
                ans=mid;
            }
            else{
                r=mid-1;
            }
        }
        return ans;
    }
};
posted @ 2024-01-02 20:47  lipu123  阅读(50)  评论(0)    收藏  举报