剑指 Offer II 017. 含有所有字符的最短字符串

  1. class Solution {
  2. public String minWindow(String s, String t) {
  3. // 返回含有t最短子字符串
  4. if (s == null || t == null) return "";
  5. char[] sChars = s.toCharArray();
  6. char[] tChars = t.toCharArray();
  7. int left = 0, right = 0, valid = 0, minLen = Integer.MAX_VALUE, start = 0, len = s.length();
  8. Map<Character, Integer> windows = new HashMap<>();
  9. Map<Character, Integer> need = new HashMap<>();
  10. // init
  11. for (char c : tChars) {
  12. need.put(c, need.getOrDefault(c, 0) + 1);
  13. }
  14. // slide windows
  15. while (right < len) {
  16. char add = sChars[right];
  17. right++;
  18. if (need.containsKey(add)) {
  19. // first:increase character count
  20. windows.put(add, windows.getOrDefault(add, 0) + 1);
  21. if (windows.get(add).equals(need.get(add))) {
  22. valid++;
  23. }
  24. }
  25. // shrink left
  26. while (valid >= need.size()) {
  27. if (valid == need.size()) {
  28. if (right - left < minLen) {
  29. minLen = right - left;
  30. start = left;
  31. }
  32. }
  33. char remove = sChars[left];
  34. if (need.containsKey(remove)) {
  35. int beforeCount = windows.get(remove);
  36. if (need.get(remove).equals(beforeCount)) {
  37. valid--;
  38. }
  39. windows.put(remove, beforeCount - 1);
  40. }
  41. left++;
  42. }
  43. }
  44. return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
  45. }
  46. }