LeetCode热题100——滑动窗口

所谓滑动窗口,个人理解就是——锁定一个范围,对范围内的数据进行操作,因为其范围可以变化,所以就叫滑动窗口。

滑动窗口一般的操作是:若增加某一个元素到滑动窗口里面,就让其右边界+1,若删除,则左边界-1

提示:寻找最长的不含重复字符的子串,相当于是确保滑动窗口内不含有重复字符的同时,让滑动窗口尽可能地大一点

确保不含有重复字符,可以采用哈希表地方法,遇到某个字符就让mp[s[i]]++,把字符从滑动窗口删除则是--,而且哈希表能够快速地定位新加入的字符是否已经存在在滑动窗口内

具体做法是,遍历字符串s,每次都让mp[s[i]]++,即字符存入哈希表中,然后判断新加入的字符是否已经存在,若已经存在,则收缩滑动窗口,直到新加入的字符在哈希表中仅有一个,最后更新答案

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> mp;
        int ans=0;
        for(int i=0,j=0;i<s.size();i++)
        {
            mp[s[i]]++;
            //如果mp[s[i]]>1,代表s[i]这个字符在滑动窗口已经出现两次以上
            while(mp[s[i]]>1) mp[s[j++]]--;
            ans=max(ans,i-j+1);
        }
        return ans;
    }
};

 提示:以给定的p的长度固定滑动窗口的大小,然后判断窗口内的字符串是否为异位词

判断是否为异位词,可以采用哈希表的方法,让一个字符串的每个字符都存入哈希表中,另一个字符串存入另一个哈希表,若两个哈希表的字符种类以及数量都一样,则是异位词

首先遍历p,将其存入哈希表当中(这里用了一个哈希表,值是一个pair,分别代表s的滑动窗口和p,如果感觉看起来不舒服,可以换成两个哈希表),然后先初始化滑动窗口,只要s[i]在p内,就将其放入滑动窗口(这里是为了简化操作,因为如果两个字符串易位,那么其字符的种类肯定是一样的,不存在于p的字符就不放入了),后面就是遍历s字符串,固定滑动窗口的大小,每一次都放入一个字符并且删除一个字符,然后判断是否为异位词即可

class Solution {
public:
    bool isEqual(unordered_map<char,pair<int,int>>& mp){
        for(auto x:mp){
            if(x.second.first != x.second.second)return false;
        }
        return true;
    }
    vector<int> findAnagrams(string s, string p) {
        int len1=s.size();
        int len2=p.size();
        vector<int> res;
        if(len1<len2)return res;
        unordered_map<char, pair<int, int>> mp;//pair前面对应s的窗口内该字符的数,后面对应p
        //将p放入哈希表
        for(int i=0;i<len2;i++){
            mp[p[i]].second++;
        }
        //初始化滑动窗口
        for(int i=0;i<len2;i++){
            //这个判断属于是简化操作,也可以不判断直接放入
            if(mp[s[i]].second) mp[s[i]].first++;
        }
        if(isEqual(mp)) res.push_back(0);
        int left=0;
        for(int i=len2;i<len1;i++){
            if(mp[s[left]].second) mp[s[left]].first--;
            if(mp[s[i]].second) mp[s[i]].first++;
            left++;
            if(isEqual(mp)) res.push_back(left);
        }
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值