根据网上所言,滑动窗口算法用于求满足某种条件的最短或最长子数组(子串)如:
1)最小摘要
2)sum大于target的最短子数组
3)最长的无重复字符的子串
4)最长的最多有k个不同字符的子串
本次做了道最长无重复字符子串的题目
题目链接: https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
不多加以思考,硬套模板,尝试能否解出题目。
首先是基础的声明:
字符串长度为0,那么结果肯定是0,就返回。
由于题目要求求不重复的子串,不重复那肯定是集合,所以用集合来存子串。
max_length就是所求的解。
left就是滑动窗口必备的左坐标。
然后开始套:
先是窗口右端扩展,加进s[j],更新条件,虽然不知道为什么,但是扩展肯定是在child中插入s[j]了,故:
第二步,不满足的条件:
往这边思考,寻找不重复的子串的不满足条件那就是找到重复字符了,所以while里面就是子串有字符重复的判定。
如果find函数的返回值和end函数相等,说明直到找到最后面都找不到,而一旦不相等就说明重复了。
第三步,移除左端的s[j],更新条件,然后i++,这里的i++指的应该是left坐标。
第四步,此时重新满足条件,和最优比较并记录。那就是要记下最大长度咯。
j-left+1就是滑动窗口包住的子串的长度。
套完了,试着提交一下。
并没有能过呢~
什么原因呢?分析一下整体逻辑
再提交下试试:
1.思路:滑动窗口。维护一个窗口,窗口记录着以当前窗口右端字符为最右字符的最长不重复子串。随着窗口右部的移动,能遍历所有的最长不重复子串。用一个数组记录每个字符在窗口扫过(包括窗口内)的最右位置。为了保证窗口字符不重复。右部每移入一个字符,如果该字符存在原窗口中,窗口左端必须更新为该字符的原来最近位置加1;该字符不存在,则左端不更新。我的解答跟官方的解答并没有太大的性能差异。虽然我的思路不一样,但是我在实现的过程中也是基于一个滑动的向右扫描。官方解答的高明之处在于用数组记录了每个字符的最近出现位置,对移入的每个字符,直接查看它的上次位置。而我则是要在已有子串中一个一个与该字符判等,当不重复子串长度较长时,性能较差。