LeetCode : 字符串的排列

字符串的排列

题目叙述:

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例:

示例1:
输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).
示例2:
输入: s1= “ab” s2 = “eidboaoo”
输出: False

注意:

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

解题思路:

这是一个变形后的滑动窗口问题,我们窗口的大小就按照的是s1的长度,将s2向后移动进行匹配,如果相同也就是在窗口中s2中的字符和s1长度相等的并且字符出现次数都相等即为匹配相似。从前往后移动窗口也就是将区域进行后移。直到窗口的右边界超出s2字符串越界结束。在窗口移动的过程中需要将移动过的地方要除去他也就是diff[s2.charAt(i – s1.length()) – ‘a’]–;然后加上新的地方也就是diff[s2.charAt(i) – ‘a’]++;进行移动。
时间复杂度为O(n)

实现代码:
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if (s1 == null || s2 == null || s1.length() > s2.length()) {
            return false;
        }
        int[] cnt1=new int[26];
        int[] cnt2=new int[26];
        //窗口大小为s1的长度,建立窗口
        for(int i=0;i<s1.length();++i){
            cnt1[s1.charAt(i)-'a']++;
            cnt2[s2.charAt(i)-'a']++;
        }
        int[] diff=new int[26];
        for(int i=0;i<diff.length;++i){
            diff[i]=cnt2[i]-cnt1[i];
        }
        for(int i=s1.length();i<s2.length();++i){
            if(isSame(diff)){
                return true;
            }
            //对窗口进行移动。
            diff[s2.charAt(i - s1.length()) - 'a']--;
            diff[s2.charAt(i) - 'a']++;
        }
        return isSame(diff);
    }
    //判断s2中的字符和s1长度相等的并且字符出现次数都相等说明s1和这一段子串的排序之一
     public boolean isSame(int[] diff) {
        for (int i = 0; i < diff.length; i++) {
            if (diff[i] != 0) {
                return false;
            }
        }
        return true;
    }
}
    原文作者:一萍之春
    原文地址: https://www.jianshu.com/p/846c50c1c0ab
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞