滑动窗口最经典的题目

主要要思考4个问题

  • 当移动right时,也就是加入字符,需要更新哪些数据
  • 什么条件下,窗口应该暂停扩大,开始移动left窗口
  • 当移动left缩小窗口时,应该更新哪些数据
  • 我们要的结果是在扩大窗口时还是缩小窗口时进行更新

    2与4其实是对称的,

  1. public String minWindow(String s, String t) {
  2. Map<Character, Integer> needs = new HashMap<>();
  3. Map<Character, Integer> windows = new HashMap<>();
  4. int left = 0;
  5. int right = 0;
  6. int valid = 0;
  7. int start = 0;
  8. int len = Integer.MAX_VALUE;
  9. char[] tC = t.toCharArray();
  10. char[] sC = s.toCharArray();
  11. for (char c : tC) {
  12. needs.put(c, needs.getOrDefault(c, 0) + 1);
  13. }
  14. while (right < s.length()) {
  15. char c = sC[right];
  16. right++;
  17. if (needs.containsKey(c)) {
  18. windows.put(c, windows.getOrDefault(c, 0) + 1);
  19. if (windows.getOrDefault(c, 0).equals(needs.get(c))) {
  20. valid++;
  21. }
  22. }
  23. while (valid == needs.size()) {
  24. if (right - left < len) {
  25. start = left;
  26. len = right - left;
  27. }
  28. char d = sC[left];
  29. left++;
  30. if (needs.containsKey(d)) {
  31. if (windows.getOrDefault(d, 0).equals(needs.get(d))) {
  32. valid--;
  33. }
  34. windows.put(d, windows.getOrDefault(d, 1) - 1);
  35. }
  36. }
  37. }
  38. return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
  39. }

类似题目:

567. 字符串的排列

438. 找到字符串中所有字母异位词

3. 无重复字符的最长子串