算法思想----滑动窗口

不含重复元素的最长子串

 思想:

1:初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。

2:先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串包含重复的字符串

3:此时转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不包含重复的字符串。

4:重复2,3,直到 right指针到达字符串 S 的结尾

这里面要涉及-----查找表的增加和删除

代码实现:

#include<iostream>
#include<vector>
#include<set>
#include<string>
using namespace std;
class soluction{
public:
   int lengthOfLongestSubstring(string s){
    //初始化变量
    int lp=0,rp=0;//左右指针指向第一个元素
    int curLength=0,maxLength=0;//一个记录当前滑动窗口长度,一个记录待返回最大值
    //定义set查找表
    set<char> ss;//注意这里是单个字符
    //具体实现
    while(rp<s.length()){//右指针遍历完字符串后,程序结束
        if(ss.find(s[rp])==ss.end()){//右指针指向字符不在查找表set中
            ss.insert(s[rp]);
            //更新curLength和maxLength
            curLength++;
            if(maxLength<curLength) maxLength=curLength;
            rp++;//右指针右移动
        }
        else{//需要左指针右移,直至没有重复元素
            while(ss.find(s[rp])!=ss.end()){
                ss.erase(s[lp]);//查找表删去左指针
                //更新变量
                curLength--;
                lp++;
            }
            //此时窗口没有右指针元素
            ss.insert(s[rp]);
            rp++;
            curLength++;
            /*
              该种情况不必更新maxLength,一定小于curLength
            */
        }
    }
    return maxLength;
   }
};

 另解:

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
class soluction{
public:
   int lengthOfLongestSubstring(string s){
    int lp=0,rp=0;//左右指针指向第一个元素
    int maxLength=0;//记录待返回最大值
    set<char> m;
    for(;rp<s.length();rp++){
        while(m.find(s[rp])!=m.end()){
           m.erase(s[lp]);
           lp++;
        }
        m.insert(s[rp]);
        maxLength=max(maxLength,rp-lp+1);
    }
    return maxLength;
   }
};
int main(){
    string s="asdfgasedsaf";
    cout<<soluction().lengthOfLongestSubstring(s);
    return 0;
}

代码简化了很多,其实就是把缩小窗口的步骤提前,然后每次在增大窗口的过程中,更新变量

int lengthOfLongestSubstring(string s){
    int lp=0,rp=0;//左右指针指向第一个元素
    int maxLength=0;//记录待返回最大值
    set<char> m;
    while(rp<s.length()){
        /*需要缩小窗口的操作--查找表存在了s[rp]*/
        while(m.find(s[rp])!=m.end()){
           m.erase(s[lp]);//删左指针对应元素
           lp++;//左指针右移
        }
        /*增大窗口的操作*/
        m.insert(s[rp]);
        maxLength=max(maxLength,rp-lp+1);
        rp++;
    }
    return maxLength;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值