java滑动窗口实现 76. 最小覆盖子串 和 438. 找到字符串中所有字母异位词

76. 最小覆盖子串
438. 找到字符串中所有字母异位词
两个都是字符串里面使用滑动窗口,我认为有着他们的特定和共性,所以总结出来。
第一个题的窗口大小是变化的,第二个题使用的是固定大小的滑动窗口。
题解写好了注释,实在看不懂的话,拿出纸和笔推演一下就懂了。

  1. 最小覆盖子串:
class Solution {
    public String minWindow(String s, String t) {
       int[] temp = new int[123];//模拟所有的字母。
       for(int i = 0; i < t.length(); ++i){//在arr中记录下t中字符出现次数。
           temp[t.charAt(i)]++;
       }

       int left = 0, right = 0;//定义左右边界。
       int count = t.length(); //用来记录s中。
       int start = 0;//用来记录最小子串的开始下标
       int min = Integer.MAX_VALUE;//用来记录最小子串长度。
       while(right < s.length()){
           char c = s.charAt(right);
           if(temp[c] > 0){
               count--;//发现一个t中含有的字符
           }
           temp[c]--;//发现过的字符,就不用重复使用了。
           if(count == 0){
               while(left < right && temp[s.charAt(left)] < 0){//left移到第一个等于0的字符,也就是满足条件的子串的开始下标。
                   temp[s.charAt(left)]++;//把之前的填好。
                   left++;
               }
               if(right - left + 1 < min){//如果出现更小的子串。
                   min = right - left + 1;
                   start = left;
               }
               temp[s.charAt(left)]++;//窗口左边界收缩
               left++;
               count++;
           }
           right++;//窗口有边界扩充。
       }
       return min == Integer.MAX_VALUE?"":s.substring(start, start+min);
    }
}
  1. 找到字符串中所有字母异位词
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> result = new ArrayList<>();
        if(p.length() > s.length()) return result;//特殊情况直接返回
       int[] arr = new int[26];//模拟26位小写字母
       for(char data : p.toCharArray()){//在arr中记录下p中字符出现次数
           arr[data - 'a']++;
       }
       
       int left = 0, right = 0;//定义左右边界,这个窗口的大小是固定的。
       int count = p.length();//记录窗口中还需要多少个p中的字符。
       for(; right< p.length(); ++right){//固定滑动窗口。
           if(--arr[s.charAt(right) - 'a'] >= 0) count--;//如果这个值--之后还大于等于0,说明是p中的字符。
       }
       if(count == 0) result.add(0);//窗口中字符满足条件了。
       while(right <  s.length()){//开始滑动
           if(++arr[s.charAt(left++) - 'a'] > 0) count++;//左边界收缩的时候,将arr恢复,并且如果自增大于零,说明弹出了一个p中字符,count++
           if(--arr[s.charAt(right++) - 'a'] >= 0) count--;//右边界扩充,如果这个值--之后还大于等于0,说明是p中的字符。
           if(count == 0) result.add(left);//窗口中字符满足条件了。
       }
       return result;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黑cc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值