写在前面:
这里主要是说数组or字符串问题里边经常会用到的“滑动窗口”,不是网络里边那个(那个其实我也有总结过,不过没整理成博客,等看到那块的时候来写)。
什么是滑动窗口?
画个图先直观的形成一个印象:
有了印象之后,滑动窗口经常用来解决子串的问题,从图上也能看出来,就是设置一个区间,然后在这个字符串or数组上滑动。
有了是什么之后,那我们就看看为什么。
为什么要用滑动窗口
假如我们要求这个字符串里不重复的最长子串长度的话,很自然的想法是里外循环:
我们从头开始找,找到end=3的时候我们发现有重复了,说明从start = 0 开始的最长不重复子串长度是3,然后我们就从start = 1开始再找,当end = 4 时我们发现重复,于是我们继续将start往后推,这样的话是能解决问题的,不过时间复杂度是O()。
如果用滑动窗口的话,我们是不是需要判断窗口什么时候移,怎么移?
大概思路就是这样,那怎么直到start每次移动多少呢?
用一个Map<字符,下次的位置>来记录,比如说一开始end = 0的时候我们遍历到字符's',那么我们将它作为key加入map,value则是它的下一个位置,表示说当你遇到‘s’字符时,你滑动到位置开始将不会重复..
怎么实现?
这里是leetcode的第3题:无重复字符的最长子串,上边也是拿它举例的。
public int lengthOfLongestSubstring(String s){
int result = 0;
Map<Character,Integer> map = new HashMap<>();
for(int start = 0, end = 0; end < s.length(); end++){
if(map.containsKey(s.charAt(end))){
start = Math.max(start, map.get(s.charAt(end)));
}
map.put(s.charAt(end),end + 1);
result = Math.max(result,end - start + 1);
}
return result;
}
先写到这,后边遇到这类问题再来补充。