zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Leetcode 567. 字符串的排列

LeetCode 字符串 排列
2023-09-14 09:07:04 时间

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

示例 1:

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

示例 2:

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

提示:

  • 1 <= s1.length, s2.length <= 104
  • s1 和 s2 仅包含小写字母

Code:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        
        // 排除异常的边界情况,也限定了模式串的长度
        if(s1.size() > s2.size()) return false;
        
        // 匹配采用的窗口大小为模式串大小
        int windowSize = s1.size();
        
        // 模式串的字典:可以看做一种频率分布
        vector<int> hashmap1(26, 0);
        // 动态更新的匹配窗口字典
        vector<int> hashmap2(26, 0);
        
        // 构建字典
        for(int i = 0; i < windowSize; i++) {
            hashmap1[s1[i] - 'a']++;
            hashmap2[s2[i] - 'a']++;
        }
        
        // 对于每一轮滑窗查询,如果两个字典相等(频率分布一致),则命中
        for(int i = windowSize; i < s2.size(); i++) {
            // 两个字典相等(频率分布一致),则命中
            if(hashmap1 == hashmap2) return true;
            
            // 否则,向右滑窗:滑窗对于 hash 表的操作变为对应频率的增减
            hashmap2[s2[i - windowSize] - 'a']--;
            hashmap2[s2[i] - 'a']++;
        }
        
        // 整个算法采用左闭右开区间,因此最后还有一个窗口没有判断
        return hashmap1 == hashmap2;
    }
};