leetcode 6069. 最大波动的子字符串—(每日一难day22)

6069. 最大波动的子字符串

字符串的 波动 定义为子字符串中出现次数 最多 的字符次数与出现次数 最少 的字符次数之差。

给你一个字符串 s ,它只包含小写英文字母。请你返回 s 里所有 子字符串的 最大波动 值。

子字符串 是一个字符串的一段连续字符序列。

示例 1:

输入:s = “aababbb”
输出:3
解释: 所有可能的波动值和它们对应的子字符串如以下所示:

  • 波动值为 0 的子字符串:“a” ,“aa” ,“ab” ,“abab” ,“aababb” ,“ba” ,“b” ,“bb” 和 “bbb” 。
  • 波动值为 1 的子字符串:“aab” ,“aba” ,“abb” ,“aabab” ,“ababb” ,“aababbb” 和 “bab” 。
  • 波动值为 2 的子字符串:“aaba” ,“ababbb” ,“abbb” 和 “babb” 。
  • 波动值为 3 的子字符串 “babbb” 。 所以,最大可能波动值为 3 。

示例 2:

输入:s = “abcde”
输出:0
解释: s 中没有字母出现超过 1 次,所以 s 中每个子字符串的波动值都是 0 。

提示:

1 <= s.length <= 1e4
s 只包含小写英文字母。

解析

  1. 枚举每个最大最小值,像这种字符为26小写字母,很多都有枚举的做法。
  2. 序列中需要同时包含最大 ,最小字符。不能没有最小字符情况。
  3. 我们可以设定,只有遇到最小字符时才可以计算最大c1, 最小c2的差,可以怎么做呢? 用一个变量cntc2记录最大最小的差值,如果没有遇到c2就将两者差值cntc2设置为一个小于0的数(返回值是>=0)
  4. 还需要一个变量cntc1,在遇到c2之前,或者遇到下一个c2之前记录c1,c2两者的最大差,以至于在遇到下一个c2 时得到两者的差。
  5. 为什么cntc1的值最小为0? 例如abbaab,cntc1更确切的表示为:前边所有字符中a - b的最大差,为下一次遇到b做准备。

例如:aabaab, 最大为a, 最小为b;遇到第一个b之前cntc2=2,遇到b,cntc2=1,这时就能给cntc1赋值了(之前一直为INT_MIN),cntc1=cntc1=1;遇到第二个b了,cntc2=3,cntc1=cntc2=3;

class Solution {
public:
    // meijv
    int check(char c1,char c2,string s){
        int n=s.size();
        int cntc1=INT_MIN;
        int cntc2=0;
        int res=0;
        for(int i=0;i<n;i++){
            char a=s[i];
            if(a==c1){
                cntc2--;
                cntc1=cntc2;
                cntc2=max(cntc2,0);
            }
            // 遇到了一个最大字符
            else if(a==c2){
                cntc2++;
                cntc1++;
            }
            // 每次比较的都是当前序列之前两者的差,如果没有遇到b
            // cntc1一直都是小于0,如果遇到的b大于a,此值依然是小于0
            // 例如:abbaa
            // cntc1中记录的是为下一次遇到b准备的值
            //例如,abbaaab,到第三个b,前边的最大差数目为3
            // aabaaab,前边最大差数目为4
            res=max(res,cntc1);
        }
        return res;
    }
    int largestVariance(string s) {
        int res=0;
        unordered_set<char> se;
        for(auto a : s){
            se.insert(a);
        }
        // 枚举最大最小字符
        for(auto a : se){
            for(auto b : se){
                if(a==b)
                    continue;
                res=max(check(a,b,s),res);
            }
        }
        return res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值