当前位置:   article > 正文

算法——滑动窗口之最小覆盖子串

算法——滑动窗口之最小覆盖子串

8.最小覆盖子串

题目:. - 力扣(LeetCode)

我们很容易就能想到暴力解法,就是暴力枚举:

我们找到满足条件的这个子串后,就要将left++,然后right回到left的位置开始遍历,寻找下一个满足条件的子串,期间用哈希表来统计,判断是否满足条件

我们在暴力解法上进行优化:

(1)实际上当找到一个满足条件的子串后,right没必要回到left的位置,因为哈希表中已经存有left到right的信息

(2)left不只是简单的++,因为left++后,可能会出现2种情况:

①子串还是满足条件,那么left还要继续++,

②子串不满足条件,那么left不用在继续++

因此这种双指针同向运动的题目就是我们熟悉的滑动窗口

我们用in来表示进窗口的元素,out来表示出窗口的元素,hash1记录t中每个字符的个数,hash2记录窗口中每个字符的个数

(1)进窗口:hash2(in)++

(2)判断 :判断hash1和hash2中记录的字符情况是否一致,是的话更新结果,并出窗口

(3)出窗口:hash2(out)++

对于判断的优化:我们在前面的题目做过类似的判断优化方法,即用count来记录有效字符的个数

但是在这道题中两个哈希表不是简单的一一对应的关系,hash2中的字符可能会出现多次

所以我们应该判断的是字符的种类,即当hash1[in] == hash2[in]时,count++;而用kinds记录t中字符的种类,当kinds == count时,更新条件

题解:

  1. class Solution {
  2. public static String minWindow(String s, String t) {
  3. int[] hash2 = new int[80];
  4. int[] hash1 = new int[80];
  5. int kinds = 0;
  6. for(char c : t.toCharArray()){
  7. if(hash1[c - 'A']++ == 0){
  8. kinds++;
  9. }
  10. }
  11. int minLen = s.length() + 1;
  12. int len = s.length();
  13. int begin = -1;
  14. for(int left = 0,right = 0,count = 0;right < s.length();right++){
  15. char in = s.charAt(right);
  16. hash2[in - 'A']++;
  17. if(hash2[in - 'A'] == hash1[in - 'A']){
  18. count++;
  19. }
  20. while(count == kinds && left <= right){
  21. int tmp = right - left + 1;
  22. if(tmp < minLen){
  23. begin = left;
  24. minLen = tmp;
  25. }
  26. char out = s.charAt(left);
  27. if(hash2[out - 'A'] == hash1[out - 'A']){
  28. count--;
  29. }
  30. hash2[out - 'A']--;
  31. left++;
  32. }
  33. }
  34. return minLen == s.length()+1 ? "" : s.substring(begin,begin+minLen);
  35. }
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/244258
推荐阅读
相关标签
  

闽ICP备14008679号