567. Permutation in String

问题

Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string's permutations is the substring of the second string.

例子

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
**Explanation: **s2 contains one permutation of s1 ("ba").

Input:s1= "ab" s2 = "eidboaoo"
Output: False

分析

开辟一个大小为26的滑动窗口,保存字符串的字符元素出现的次数,字符串的长度和s1的长度一致。

例如s1=ab, s2=eibaooo.则s1对应的滑动窗口为:
11000000000000000000000000
s2前两个字符对应的滑动窗口为:
00001000100000000000000000

首先用s1和s2的前s1长度段初始化滑动窗口,s1出现的字符次数减一,s2的前s1长度段出现的字符次数加一。然后滑动窗口从s2的左边向右边滑动。每滑动一次,把从滑动窗口左侧滑出的字符的次数减一,把从滑动窗口右侧滑入的字符的次数加一。统计滑动窗口次数为0的个数,如果等于26则说明在s2找到了s1的一个排列。

要点

  1. 使用map来表示字符串的信息(map可以用数组模拟,提高效率);
  2. 滑动窗口。

时间复杂度

O(n), n是s2的长度

空间复杂度

O(1)

代码

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        vector count(26, 0);
        for (int i = 0; i < s1.size(); i++) {
            count[s1[i] - 'a']--;
            count[s2[i] - 'a']++;
        }
        
        int zeroNum = 0;
        for (int i = 0; i < 26; i++) 
            zeroNum += count[i] == 0 ? 1 : 0;
        if (zeroNum == 26) return true;
        
        for (int i = s1.size(); i < s2.size(); i++) {
            count[s2[i] - 'a']++;
            if (count[s2[i] - 'a'] == 0) zeroNum++;
            if (count[s2[i] - 'a'] == 1) zeroNum--;
            
            count[s2[i - s1.size()] - 'a']--;
            if (count[s2[i - s1.size()] - 'a'] == 0) zeroNum++;
            if (count[s2[i - s1.size()] - 'a'] == -1) zeroNum--;
            
            if (zeroNum == 26) return true;
        }
        
        return false;
    }
};

你可能感兴趣的:(567. Permutation in String)