滑动窗口之最长子串模板之最长无重复子串

JavaScript016

滑动窗口之最长子串模板之最长无重复子串,第1张

我们经常会遇见许多设计到字符串的题目,很多中等难度的题目都会用上滑动窗口算法,所以就稍微学习了下。

根据网上所言,滑动窗口算法用于求满足某种条件的最短或最长子数组(子串)如:

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;该字符不存在,则左端不更新。我的解答跟官方的解答并没有太大的性能差异。虽然我的思路不一样,但是我在实现的过程中也是基于一个滑动的向右扫描。官方解答的高明之处在于用数组记录了每个字符的最近出现位置,对移入的每个字符,直接查看它的上次位置。而我则是要在已有子串中一个一个与该字符判等,当不重复子串长度较长时,性能较差。