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