无重复字符的最长子串【滑动窗口】

题目是P3无重复字符的最长子串
在这里插入图片描述
对于字符串abcbcbb而言,我们从头遍历,查找以遍历处开始往后的最长不重复子串,如下:

以 (a)bcabcbb 开始的最长字符串为 (abc)abcbb;
以a(b)cabcbb 开始的最长字符串为 a(bca)bcbb;
以ab( c )abcbb 开始的最长字符串为 ab(cab)cbb;
以abc(a)bcbb 开始的最长字符串为 abc(abc)bb;
以abca(b)cbb 开始的最长字符串为 abca(bc)bb;
以abcab( c )bb 开始的最长字符串为 abcab(cb)b;
以abcabc(b)b 开始的最长字符串为 abcabc(b)b;
以abcabcb(b) 开始的最长字符串为 abcabcb(b)。

我们可以发现,如果我们依次枚举子串的起始位置,那么子串的结束位置也是递增的,此结论很容易证明为真,因此我们考虑用这一性质,采用滑动窗口的方法来解决问题:

  • 我们使用两个指针来记录:左指针i记录了当前遍历的位置也即滑动窗口的左起始点的位置;右指针right记录了滑动窗口的截至位置,无重复子串的长度即为right-i+1
  • 在每一步的操作中,我们将左指针右移一位,然后不断的右移右指针,直到发现重复的元素为止,记录下以i为起始结点的子串的长度
  • 枚举结束后,所有记录的长度的最大值即为最长的无重复字符子串

代码如下:

int lengthOfLongestSubstring(string s) {
    unordered_set<char>se;
    int n=s.size();
    int ans=0;
    int right=-1;
    for(int i=0;i<n;i++){
        if(i!=0) se.erase(s[i-1]); //擦去左指针的前一个元素
        while(right+1<n&&se.count(s[right+1])==0){ //右指针的下一位如果没出现过
            se.insert(s[right+1]); //插入下一个元素
            ++right; //右指针右移
        }
        ans=max(ans,right-i+1); //时刻记录每一次遍历后的最大长度
    }
    return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值