最简单理解滑动窗口
文章目录
引用labuladong的一个关于滑动窗口的口诀 「滑动窗口老猛男,子串问题全靠它。左右指针滑窗口,一前一后齐头进。」
先看一段代码
public static int maxStrSlidingWindow(String str) {
// 定义一个滑动窗口
// 1. 开始窗口中只有一个字母
// 2. 窗口开始滑动加入第二个字母,如果distinct后count和窗口中元素相同,则说明没有重复
// 3. 继续窗口中增加元素,如果如果distinct后count小于窗口中元素了,说明开始有重复了
// 4. 删除窗口最前端(左端)元素,继续添加,窗口中保留的元素就是最长无重复子串
LinkedList<Character> l = new LinkedList<>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
l.add(c);
long count = l.stream()
.distinct()
.count();
if (l.size() != count) {
l.removeFirst();
}
}
return l.size();
}
这段代码是干什么的呢?
这段代码其实就是一个leecode的「给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度」题,使用滑动窗口来解答的代码实现
也就是labuladong口诀中子串问题全靠它的具体体现。
左右指针滑窗口,一前一后齐头进 怎么理解
也就是代码中注释写的
- 定义了一个窗口`LinkedList
- 往这个List右侧add元素(也就是右指针滑动),一直添加元素到满足题目中(不含有重复字符)的临界点(也就是添加到元素已经在链表中出现过)
- 这时候需要收缩左侧指针
l.removeFirst();,注意这时候每次实际只移除了一个元素 一前一后齐头进就是add一个,如果列表中有重复数据就会移除一个,也就是后进一步前跟进一步(右侧add,左侧remove),此时List内部对象是存在重复对象,但List整体长度是曾经出现过的 不含有重复字符的 最长子串 的长度的大小
一个实际的例子
public static void main(String[] args) {
String str = "abcdefgaaaabcbbcmn";
System.out.println(maxStrSlidingWindow(str));
}
遍历过程中List包含的元素情况如下:
["a"]1
["a","b"]2
["a","b","c"]3
["a","b","c","d"]4
["a","b","c","d","e"]5
["a","b","c","d","e","f"]6
["a","b","c","d","e","f","g"]7
["a","b","c","d","e","f","g","a"]7
["b","c","d","e","f","g","a","a"]7
["c","d","e","f","g","a","a","a"]6
["d","e","f","g","a","a","a","a"]5
["e","f","g","a","a","a","a","b"]5
["f","g","a","a","a","a","b","c"]5
["g","a","a","a","a","b","c","b"]4
["a","a","a","a","b","c","b","b"]3
["a","a","a","b","c","b","b","c"]3
["a","a","b","c","b","b","c","m"]4
["a","b","c","b","b","c","m","n"]5
finally["b","c","b","b","c","m","n"]7
相似文章
评论 · 0
文章作者 pengxiaochao
上次更新 2022-07-10
许可协议 不允许任何形式转载。
还没有评论,写下第一条吧。