zoukankan      html  css  js  c++  java
  • 567.字符串的排列

    给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

    换句话说,第一个字符串的排列之一是第二个字符串的子串。

    示例1:

    输入: s1 = "ab" s2 = "eidbaooo"
    输出: True
    解释: s2 包含 s1 的排列之一 ("ba").

    示例2:

    输入: s1= "ab" s2 = "eidboaoo"
    输出: False

    注意:

    输入的字符串只包含小写字母
    两个字符串的长度都在 [1, 10,000] 之间

    思路:

      • 滑动窗口 + 左右指针,和 "438.找到字符串中所有字母异位词"、"76.最小覆盖子串";
      • 用 count 记录滑动窗口中 s1 中字符出现的次数,当某一个字符出现的次数,超过 s1 中的次数,则不用记录;
      • 当 count == 0 时,表示窗口中的字符个数等于 s1 中的字符个数,则停下来判断是否满足子串这一个条件。

    class Solution {
        public boolean checkInclusion(String s1, String s2) {
            int n1 = s1.length(), n2 = s2.length();
            if(n1 > n2) return false;
            int left = 0, right = 0, count = n1;
            int[] needs = new int[26]; // s1 的字符统计
            int[] windows = new int[26]; //滑动窗口
            for(char c : s1.toCharArray()) needs[c-'a']++; // s1 数组
            while(right < n2){
                char cr = s2.charAt(right);
                right++; // 窗口右移
                if(needs[cr-'a'] > 0){
                    windows[cr-'a']++;
                    if(windows[cr-'a'] <= needs[cr-'a']) count--; // count是否改变
                }
                while(count == 0){
                    if(right - left == n1) return true; //满足条件,返回 true
                    char cl = s2.charAt(left);
                    windows[cl - 'a']--;
                    if(needs[cl - 'a'] > 0){ //如果这个字符也是 s1 中的字符
                        if(windows[cl - 'a'] < needs[cl - 'a']) count++; //查看是否更新 count
                    }
                    left++; //缩小窗口
                }
            }
            return false;
        }
    }
  • 相关阅读:
    div居中方法总结
    windows下配置nginx环境
    webpack+babel+react操作小结
    JavaScript数组常用操作总结
    MyBatis使用Generator自动生成代码
    如何上Chrome谷歌商店
    深入理解Spring IOC
    SpringMVC概要总结
    mybatis防止sql注入
    Redis和Memcache的区别分析
  • 原文地址:https://www.cnblogs.com/luo-c/p/13959523.html
Copyright © 2011-2022 走看看