带你读《图解算法小抄》二十、滑动窗口(5)

简介: 带你读《图解算法小抄》二十、滑动窗口(5)

带你读《图解算法小抄》二十、滑动窗口(4)https://developer.aliyun.com/article/1347996?groupCode=tech_library

 

6.判断字符串排列


给定两个字符串s1和s2,判断s2是否包含s1的任意排列。如果是,返回true;否则,返回false。

 

示例:

 

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

 

输入:s1 = "ab",s2 = "eidboaoo" 输出:false 解释:s2 并不包含 s1 的任意排列。

1题目分析与解题步骤:

这个问题可以使用滑动窗口算法来解决。我们可以维护一个窗口,大小等于s1的长度,在s2上滑动窗口,并比较窗口内的字符是否与s1中的字符构成相同的排列。

 

解题步骤如下:

 

  • 初始化两个计数器对象counter1和counter2,用于记录s1和当前窗口内字符的出现次数。
  • 遍历字符串s1,并统计每个字符的出现次数,存储在counter1中。
  • 初始化两个指针left和right,分别指向窗口的左右边界。
  • 在s2上使用滑动窗口,开始从左向右滑动窗口。
  • 在每次滑动窗口时,更新窗口内字符的出现次数counter2。同时,比较counter1和counter2是否相等,如果相等,表示当前窗口内的字符与s1中的字符构成相同的排列。
  • 如果相等,返回true。
  • 如果不相等,继续滑动窗口,即将窗口的左边界向右移动一位,并更新counter2。
  • 重复步骤5-7,直到窗口滑动到s2的末尾。
  • 如果未找到符合条件的排列,返回false。

2JavaScript解题框架:

function checkInclusion(s1, s2) {
    let counter1 = {};
    let counter2 = {};    // 统计 s1 中字符的出现次数
    for (let char of s1) {
        counter1[char] = (counter1[char] || 0) + 1;
    }    let left = 0;
let right = 0;
    while (right < s2.length) {
        // 扩大窗口
        let char = s2[right];
        counter2[char] = (counter2[char] || 0) + 1;        // 检查窗口内字符的出现次数是否与 s1 相同
        if (right - left + 1 === s1.length) {
            if (compareCounters(counter1, counter2)) {
                return true;
            }
            // 缩小窗口
            char = s2[left];
            counter2[char]--;
            if (counter2[char] === 0) {
                delete counter2[char];
            }
            left++;
        }
        right++;
}
    return false;
}
// 比较两个计数器对象的键值对是否相等function compareCounters(counter1, counter2) {
    for (let key in counter1) {
        if (counter1[key] !== counter2[key]) {
            return false;
        }
    }
return true;
}

 

在这个框架中,我们使用了两个计数器对象counter1counter2,分别用于统计s1和窗口内字符的出现次数。

 

我们首先遍历s1,统计每个字符的出现次数,存储在counter1中。然后,使用滑动窗口在s2上进行匹配。在每次滑动窗口时,我们将当前字符的出现次数添加到counter2中,并与counter1进行比较。如果两个计数器对象的键值对相等,则表示当前窗口内的字符与s1中的字符构成相同的排列。

 

最后,如果找到符合条件的排列,返回true;否则,返回false。

相关文章
|
2月前
|
算法
【算法】滑动窗口——最大连续1的个数
【算法】滑动窗口——最大连续1的个数
|
5月前
|
算法 测试技术 C++
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
|
5月前
|
机器学习/深度学习 算法
【优选算法】—— 滑动窗口类问题
【优选算法】—— 滑动窗口类问题
|
2月前
|
算法
【算法】滑动窗口——最小覆盖子串
【算法】滑动窗口——最小覆盖子串
|
2月前
|
算法
【算法】滑动窗口——找到字符串中所有字母异位词
【算法】滑动窗口——找到字符串中所有字母异位词
|
2月前
|
算法
【算法】滑动窗口——将x减到0的最小操作数
【算法】滑动窗口——将x减到0的最小操作数
|
2月前
|
算法
【算法】滑动窗口——无重复字符的最长子串
【算法】滑动窗口——无重复字符的最长子串
|
2月前
|
算法
【算法】滑动窗口——长度最小的子数组
【算法】滑动窗口——长度最小的子数组
|
2月前
|
算法 容器
【算法】滑动窗口——串联所有单词的子串
【算法】滑动窗口——串联所有单词的子串
|
2月前
|
算法
【算法】滑动窗口——水果成篮
【算法】滑动窗口——水果成篮