c++滑动窗口学习心得

滑动窗口简介:
就是保持一个固定长度的窗口,每次滑动一个位置;

例题1:
给定一个字符串 s ,请你找出其中不含有重复字符的最长连续子串的长度。

示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:

输入: s = “”
输出: 0

解题:

  • 题目含义
    这道题的意思就是给定一个字符串,然后要求你在这个字符串找到一个最长的连续不重复元素子串。
  • 题目解法:
    定义一个n,l,max,i,j;
    • n:表示字符串的长度
    • l:表示滑动窗口起点
    • max表示最大的连续不重复元素长度
    • i表示遍历数组指针
    • j表示遍历滑动窗口指针
    • 采用二重循环,每扫描一个元素(第一重),就判断是否在已有的滑动窗口内(第二重),如果在,就判断当前的滑动窗口长度是否大于max,如果大于max,就将滑动窗口的长度赋值给max,并将l赋值为第一个重复元素的下一个位置,也就是j+1,并跳出二重循环。
    • 注意:最后返回的应该是max>(i-l)?max:(i-l);(字符串本身就是最长连续不重复)

代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n=s.size();
        int l=0,max=0,i=0;
        for(;i<n;i++)
        {
            int j=l;
            for(;j<i;j++)
            { 
                if(s[j]==s[i])
                {
                    max=max>(i-l)?max:(i-l);
                    l=j+1;
                    break;
                }
            }
        }
        return max>(i-l)?max:(i-l);
    }
};

1=============
2=============
3=============

例题2:
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

示例 1:

输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).
示例 2:

输入:s1= “ab” s2 = “eidboaoo”
输出:false

提示:

1 <= s1.length, s2.length <= 104
s1 和 s2 仅包含小写字母

  • 题目含义
    给你两个字符串s1,s2,在s2中判断是否有一个子串的排列与s1相等,如果有返回true,否则返回fasle。
  • 题目解法
    • 此题目说的是子串排列是否和s1相等,也就是说不用考虑顺序,只需考虑子串中的每个字符数量是和s1中的相等即可。那么就可以固定一个存储s1大小的容器来滑动s2,如果当前的滑动框内字符和s1中的不相等,那么就向右滑动一个位置,新的字符加一,而滑动框左边那个位置的字符减一。
    • 可以定义两个vector容器(26)v1,v2,先用v1去遍历s1,v2去遍历s2(遍历s1的长度即可)把对比字符数量扫入,这里可以用字符-'a’把它转成整型,即对应下标为当前字符-'a’这个位置+1。

代码:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        vector<int> v1(26),v2(26);
        int n=s1.size(),m=s2.size();
        if(n>m) return false;
        for(int i=0;i<n;i++)
        {
            v1[s1[i]-'a']++;
            v2[s2[i]-'a']++;
        }
        if(v1==v2) return true;
        for(int i=n;i<m;i++)
        {
            v2[s2[i]-'a']++;
            v2[s2[i-n]-'a']--;
            if(v1==v2)
            return true;
        }
        return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值