【leetcode】567. 字符串的排列(permutation-in-string)(滑动窗口)[中等]

链接

https://leetcode-cn.com/problems/permutation-in-string/

耗时

解题:24 min
题解:15 min

题意

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

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

注意:

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

思路

假设:s1 的长度为 m,s2 的长度为 n。

设置一个固定长度为 m 的滑动窗口,在 s2 上滑动窗口,每次统计当前滑动窗口内 26 个小写字母的数量,并检查当前窗口内 26 个小写字母中每个字母的数量是否和 s1 的 26 个小写字母中每个字母的数量都相等,如果存在都相等的滑动窗口则说明存在一个 s2 的子串是 s1 的排列,返回 true,否则向后滑动窗口。如果窗口在 s2 上滑动到末尾都没有找到这样的子串,返回 false。

时间复杂度: O ( n ) O(n) O(n)

AC代码

class Solution {
    
    
public:
    bool check(vector<int>& s1cnt, vector<int>& s2cnt) {
    
    
        for(int i = 0; i < 26; ++i) {
    
    
            if(s1cnt[i] != s2cnt[i]) {
    
    
                return false;
            }
        }
        return true;
    }
    
    bool checkInclusion(string s1, string s2) {
    
    
        int m = s1.size();
        int n = s2.size();
        if(m > n) return false;
        
        vector<int> s1cnt(26, 0);
        vector<int> s2cnt(26, 0);
        for(auto c : s1) {
    
    
            s1cnt[c-'a']++;
        }

        // [l, r]
        int l = 0, r = 0;
        for(r = 0; r < m-1; ++r) {
    
    
            s2cnt[s2[r]-'a']++;
        }
        while(r < n) {
    
    
            s2cnt[s2[r]-'a']++;
            if(check(s1cnt, s2cnt)) {
    
    
                return true;
            }
            s2cnt[s2[l]-'a']--;
            l++;
            r++;
        }
        return false;
    }
};

猜你喜欢

转载自blog.csdn.net/Krone_/article/details/113780910