LeetCode算法日记:340.至多包含K个不同字符的最长子串

340.至多包含K个不同字符的最长子串

日期:2022/7/30

题目描述:给定一个字符串 *s* ,找出 至多 包含 k 个不同字符的最长子串 *T*

示例:

输入: s = "eceba", k = 2
输出: 3
解释: 则 T 为 "ece",所以长度为 3。

输入: s = "aa", k = 1
输出: 2
解释: 则 T 为 "aa",所以长度为 2。

思路:

双指针+哈希表

代码+解析:

class Solution {
public:
    int lengthOfLongestSubstringKDistinct(string s, int k) {
        if(k == 0) return 0;  	//k=0的话自然没有符合条件的子串
        if(s.size() == 1) return 1;   //已经排除了k=0的情况,那么不管k等于多少长度都只有1
        map<char,int> match;  //哈希表
        int len = 0;  //长度
        int kind = 0;  //不同字符的个数
        int maxLen = 0;  //最大长度,最终返回的是这个
        int start = 0,end = 0;   //双指针
        
        while(end<s.size()){
            if(start == end){
                match[s[start]] ++; //该字母的个数++
                len++;   
                kind++; 
                end++; //右指针往右移动
            }

            if(match[s[end]] == 0 && kind == k)  //遇到一个新的字符,且超出了k的限度,调整start
            {
                maxLen = max(len,maxLen);  //保存目前的len
                match[s[start]] --; //该字母的个数--
                len--;  //长度--
                if(match[s[start]] == 0)kind--; //不同字符的个数--
                start++;  //左指针往右移动
            }else //没到限度,调整end
            {
                if(match[s[end]] == 0)kind++;  //遇到新字符
                match[s[end]]++;
                len++;
                end++;
            }

            maxLen = max(len,maxLen);
        }
        return maxLen;
    }
};

执行用时:16 ms, 在所有 C++ 提交中击败了40.24%的用户

内存消耗:6.8 MB, 在所有 C++ 提交中击败了77.98%的用户

通过测试用例:142 / 142

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值