滑动窗口
面试常见的双指针实现的滑动窗口题目
滑动窗口是解决字符串问题的有效算法,通过left,right两个指针同向移动,用以维护滑动窗口的大小及其中的元素
解题模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public int lengthOfLongestSubstring(String s) { Map<Character,Integer> window = new HashMap<Character,Integer>(); int left = 0; int right = 0; int max = 0; while(right < s.length()){ Character r = s.charAt(right); right++;
if(window.containsKey(r)){ window.put(r,window.get(r)+1); }else{ window.put(r,1); }
while(window.get(r) > 1){ Character l = s.charAt(left); left++; window.put(l,window.get(l)-1); } max = Math.max(right-left,max); } return max; } }
|
3. 无重复字符的最长子串
求解1个字符串中最长的无重复子串,注意此处不是最长子序列
解题思路
移动滑动窗口的右指针,当扫描到重复元素时,左侧指针向右移动一个位置,将最左侧元素从窗口中移除,每次移动一个单位后,用最大的窗口尺寸与当前的窗口尺寸进行比较,更新最大的窗口尺寸
567. 字符串的排列
判断字符串1的排列组合中的任意一种,是否包含在字符串2中
解题思路
从暴力模拟的思路来看,求解并存储字符串的所有排列组合显然不可能,因此,将字符串的排列组合转化为存储其各个字符数量对应的HashMap,或数组进行存储
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| class Solution { public boolean checkInclusion(String s1, String s2) { int left = 0; int right = 0; int n = s2.length(); int valid = 0;
Map<Character,Integer> goal = new HashMap<Character,Integer>(); Map<Character,Integer> windows = new HashMap<Character,Integer>();
if(s1.length() > s2.length()){ return false; }
for(int i=0;i<s1.length();i++){ Character c = s1.charAt(i); if(goal.containsKey(c)){ goal.put(c,goal.get(c)+1); }else{ goal.put(c,1); } }
while(right < n){ Character c = s2.charAt(right); right++;
if(goal.containsKey(c)){ if(windows.containsKey(c)){ windows.put(c,windows.get(c)+1); }else{ windows.put(c,1); } if(windows.get(c).equals(goal.get(c))){ valid++; } }
while(right - left >= s1.length()){ if(valid == goal.size()){ return true; }
Character d = s2.charAt(left); left++; if(goal.containsKey(d)){ if(windows.get(d).equals(goal.get(d))) valid--; windows.put(d,windows.get(d)-1); } } } return false; } }
|