滑动窗口处理字符串--LeetCode003 Longest SubString without repeating characters

这篇博文主要是为了记录滑动窗口处理字符串的问题,主要参考了两篇文章,如有侵权,请联系我

csdn:https://blog.csdn.net/LVGAOYANH/article/details/77187899

github:https://github.com/liuyubobobo/Play-Leetcode/blob/master/0003-Longest-Substring-Without-Repeating-Characters/cpp-0003/main.cpp

问题描述:Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring,"pwke" is asubsequence and not a substring
 

我想的是用两层for来遍历,求出每一个位置上的最长子串,太复杂了。而且复杂度是O(n*n)

解决方案:

现在有一个复杂度为O(n)的算法——滑动窗口。滑动窗口是处理字符串和数组问题的经典方案

1 滑动窗口的思想:

顾名思义,滑动窗口就是滑动的窗口,在字符串上从左往右滑动,直到串尾。滑动窗口的窗口长度是动态变化的。因此用两个int值来表示左右边界。

2 滑动窗口怎么滑?

串首——>串尾

3 滑动窗口的大小怎么控制?即,何时改变左边界,何时改变右边界?

当前窗口里的子串s[i]...s[j]不包含字符s[j+1]时,窗口右边界右移一位。

否则,即当前窗口里的子串s[i]...s[j]包含字符s[j+1]时,窗口左边界右移一位。

4 滑动窗口用什么数据结构实现的?

先用c++里面的整数数组实现一下。int freq[256]={0}  freq[i]代表i这个字符在子串中出现的频率,这里只能是0,1.每次查看r+1这个字符是否在子串中出现,如果出现,就令滑动窗口左边界往右滑一位,同时更新freq[],因为滑动窗口往右滑了,所以左边界的字符会移出子串,所以相应的频率要减1.如果没有出现,就令右边界往右滑一位,更新freq[],使r+1位置上的字符在子串中的频率出现次数加1.

 

c++代码:

int lengthOfLongestSubString(string s)
{
    int freq[256] = {0};         //记录子串中每个字符出现的频率
    
    int l=0,r=-1;             //分别为左边界和右边界
    int ans = 0;
    
    while(r+1<s.size())
    {
        if(freq[s[r+1]]==0)          //如果字符r+1没有在子串中出现
            freq[s[++r]]++;          //右移右边界,并更新freq
        else                         //如果已经出现
            freq[s[l++]]--;          //右移左边界,更新freq,将原来的左边界的字符的频率减1,即在子串中剔除掉
        ans = max(ans,r-l+1);
    }
    return ans;
}
        
    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
滑动窗口是一种常用的算法技巧,可以用于解决一类问题,其中包括一些LeetCode上的题目。通过维护一个窗口,我们可以在线性时间内解决一些需要处理连续子数组或子字符串的问题。以下是一些常见的滑动窗口问题: 1. 最小覆盖子串(Minimum Window Substring):给定一个字符串S和一个字符串T,在S中找出包含T所有字符的最小子串。 2. 字符串的排列(Permutation in String):给定两个字符串s1和s2,判断s2是否包含s1的排列。 3. 找到字符串中所有字母异位词(Find All Anagrams in a String):给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串。 4. 替换后的最长重复字符(Longest Repeating Character Replacement):给定一个只包含大写英文字母的字符串s,你可以将一个字母替换成任意其他字母,使得包含重复字母的最长子串的长度最大化。 5. 至多包含两个不同字符的最长子串Longest Substring with At Most Two Distinct Characters):给定一个字符串s,找出至多包含两个不同字符的最长子串的长度。 以上只是几个例子,滑动窗口可以应用于更多类型的问题。在解决这些问题时,我们通常使用两个指针来表示窗口的左右边界,并根据具体问题的要求移动窗口。在每次移动窗口时,我们可以更新窗口的状态,例如统计字符出现次数、判断窗口是否满足条件等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值