【模板总结】滑动窗口一类问题

1 滑动窗口大小不变

567. 字符串的排列

在这里插入图片描述

   public boolean checkInclusion(String s1, String s2) {
      char[] str1 = s1.toCharArray();
      int m = s1.length();
      char[] str2 = s2.toCharArray();
      if(s1.length() > s2.length()){
         return false;
      }
      int[] arr1 = new int[26];
      int[] arr2 = new int[26];
      for (int i = 0; i < str1.length; i++) {
         arr1[str1[i] - 'a']++;
         arr2[str2[i] - 'a']++;
      }
      if(judge(arr1, arr2)){
         return true;
      }
      for (int i = m; i < s2.length(); i++) {
         arr2[str2[i - m] - 'a']--;
         arr2[str2[i] - 'a']++;
         if(judge(arr1, arr2)){
            return true;
         }
      }
      return false;
   }
   private boolean judge(int[] arr1, int[] arr2) {
      for (int i = 0; i < 26; i++) {
         if(arr1[i] != arr2[i]){
            return false;
         }
      }
      return true;
   }

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

在这里插入图片描述

   public List<Integer> findAnagrams(String s, String p) {
      List<Integer> res = new ArrayList<>();
      char[] str1 = s.toCharArray();
      char[] str2 = p.toCharArray();
      if(str1.length < str2.length){
         return res;
      }
      int m = p.length();
      int[] arr1 = new int[26];
      int[] arr2 = new int[26];
      for (int i = 0; i < str2.length; i++) {
         arr2[str2[i] - 'a']++;
         arr1[str1[i] - 'a']++;
      }
      if(judge(arr1, arr2)){
         res.add(0);
      }
      for (int i = m; i < str1.length; i++) {
         arr1[str1[i - m] - 'a']--;
         arr1[str1[i] - 'a']++;
         if(judge(arr1, arr2)){
             res.add(i - m + 1);
         }
      }
      return res;
   }
   private boolean judge(int[] arr1, int[] arr2) {
      for (int i = 0; i < 26; i++) {
         if(arr1[i] != arr2[i]){
            return false;
         }
      }
      return true;
   }

2 滑动窗口大小会改变

76. 最小覆盖子串

在这里插入图片描述

   public String minWindow(String s, String t) {
      char[] str1 = s.toCharArray();
      char[] str2 = t.toCharArray();
      int N1 = s.length();
      int N2 = t.length();
      int[] res = new int[2];
      Map<Character, Integer> map = new HashMap<>();
      int left = 0;
      int right = 0;
      int count = str2.length;
      int windowLen = Integer.MAX_VALUE;
      for (int i = 0; i < str2.length; i++) {
         map.put(str2[i], map.getOrDefault(str2[i], 0) + 1);
      }  
      while(right < N1){
         if(map.containsKey(str1[right])){
            if(map.get(str1[right]) > 0){
               count--;
            }
            map.put(str1[right], map.get(str1[right]) - 1);
         }
         while(count == 0){
            if(windowLen > right - left){
               windowLen = right - left;
               res[0] = left;
               res[1] = right;
            }
            if(map.containsKey(str1[left])){
               map.put(str1[left], map.get(str1[left]) + 1);
               if(map.get(str1[left]) > 0){
                  count++;
               }
            }
            left++;
         }
         right++;
      }
      if(windowLen == Integer.MAX_VALUE){
         return "";
      }
      return s.substring(res[0], res[1] + 1);
   }

面试题 17.18. 最短超串

在这里插入图片描述

   public int[] shortestSeq(int[] big, int[] small) {
      int left = 0;
      int right = 0;
      int N = big.length;
      int[] res = {};
      int count = small.length;
      int minLen = N;
      Map<Integer, Integer> map = new HashMap<>();
      for (int i = 0; i < small.length; i++) {
         map.put(small[i], 1);
      }
      while (right < N) {
         if (map.containsKey(big[right])) {
            if (map.get(big[right]) > 0) {
               count--;
            }
            map.put(big[right], map.get(big[right]) - 1);
         }
         while (count == 0) {
            if(minLen > right - left){
               minLen = right - left;
               res = new int[]{left, right};
            }
            if(map.containsKey(big[left])){
               map.put(big[left], map.get(big[left]) + 1);
               if(map.get(big[left]) > 0){
                  count++;
               }
            }
            left++;
         }
         right++;
      }
      return res;
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值