LeetCode 滑动窗口题型整理
一、滑动窗口题型模板
/* * 滑动窗口类型: 模板 */ public List<Integer> slideWindowMode(String s, String t) { // 1 根据题目返回类型定义数据结构 ArrayList<Integer> result = new ArrayList<>(); if(t.length()> s.length()) return result; // 2 新建Map, Key=字符,value=频率 HashMap<Character, Integer> map = new HashMap<>(); for(char c: t.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); // 3 定义变量 int counter = map.size(); // 目标字符串中的不同字符种类 int begin = 0, end = 0; // 窗口起始、结束点 int len = Integer.MAX_VALUE; // 4 源字符串开始遍历 while(end < s.length()) { // 5 统计每个字符 char c = s.charAt(end); if(map.containsKey(c)) { map.put(c, map.get(c) - 1); if(map.get(c) == 0) counter--; } end++; // 6 符合情况!begin~end 之间包含 t 的所有字符 while(counter == 0) { // 此时 Map 的 value 全部 <= 0 char tmpc = s.charAt(begin); if(map.containsKey(tmpc)) { map.put(tmpc, map.get(tmpc) + 1); if(map.get(tmpc) > 0) counter++; } // 7 do sth begin++; } } // 8 return result; }
二、LeetCode 中 几个滑动窗口套用模板实现
1、 76. Minimum Window Substring
https://leetcode.com/problems/minimum-window-substring/description/
public String minWindow(String s, String t) { if(t.length()> s.length()) return ""; HashMap<Character, Integer> map = new HashMap<>(); for(char c: t.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); int counter = map.size(); // 目标字符串中的不同字符种类 int begin = 0, end = 0; // 窗口起始、结束点 int len = Integer.MAX_VALUE; int head = 0; while(end < s.length()) { char c = s.charAt(end); if( map.containsKey(c) ) { map.put(c, map.get(c) - 1); if(map.get(c) == 0) counter--; } end++; while(counter == 0) { // 此时 Map 的 value 全部 <= 0 char tmpc = s.charAt(begin); if( map.containsKey(tmpc) ) { map.put(tmpc, map.get(tmpc) + 1); if(map.get(tmpc) > 0) counter++; } //---------- if(end - begin < len) { len = end - begin; head = begin; } //---------- begin++; } } if(len == Integer.MAX_VALUE ) return ""; return s.substring(head, head + len); }
2、3 Longest Substring Without Repeating Characters
https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
/* * 2、 Longest Substring Without Repeating Characters */ public int lengthOfLongestSubstring(String s) { HashMap<Character, Integer> map = new HashMap<>(); int begin = 0; // 窗口起始、结束点 int max = 0; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(map.containsKey(c)) { max = Math.max(max, i - begin); begin = Math.max(begin, map.get(c) + 1); map.put(c, i); } else { map.put(c, i); } } max = Math.max(s.length() - begin, max); return max; }
3、438. Find All Anagrams in a String
https://leetcode.com/problems/find-all-anagrams-in-a-string/description/
public List<Integer> findAnagrams(String s, String t) { ArrayList<Integer> result = new ArrayList<>(); if(s.length() < t.length()) return result; HashMap<Character, Integer> map = new HashMap<>(); for(char c: t.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); int counter = map.size(); int begin = 0, end = 0; // int head = 0; // int len = Integer.MAX_VALUE; while(end < s.length()) { char c = s.charAt(end); if( map.containsKey(c) ) { map.put(c, map.get(c) - 1); if(map.get(c) == 0) counter--; } end++; while(counter == 0) { char tmpc = s.charAt(begin); if( map.containsKey(tmpc) ) { map.put(tmpc, map.get(tmpc) + 1); if(map.get(tmpc) > 0) counter++; } //-------- if(end - begin == t.length()) result.add(begin); //-------- begin++; } } return result; }