LeetCode438题(无敌双指针——滑动窗口)

找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。

首先给出具体思路模版:

int left = 0, right = 0;

while (right < s.size()) {
    // 增大窗口
    window.add(s[right]);
    right++;
    
    while (window needs shrink) {
        // 缩小窗口
        window.remove(s[left]);
        left++;
    }
}

 滑动窗口模版

/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {
    unordered_map<char, int> need, window;
    for (char c : t) need[c]++;
    
    int left = 0, right = 0;
    int valid = 0; 
    while (right < s.size()) {
        // c 是将移入窗口的字符
        char c = s[right];
        // 右移窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...

        /*** debug 输出的位置 ***/
        printf("window: [%d, %d)\n", left, right);
        /********************/
        
        // 判断左侧窗口是否要收缩
        while (window needs shrink) {
            // d 是将移出窗口的字符
            char d = s[left];
            // 左移窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}

 代码:

vector<int> findAnagrams(string s, string t) {
    unordered_map<char, int> need, window;
    for (char c : t) need[c]++;

    int left = 0, right = 0;
    int valid = 0;
    vector<int> res; // 记录结果
    while (right < s.size()) {
        char c = s[right];
        right++;
        // 进行窗口内数据的一系列更新
        if (need.count(c)) {
            window[c]++;
            if (window[c] == need[c]) 
                valid++;
        }
        // 判断左侧窗口是否要收缩
        while (right - left >= t.size()) {
            // 当窗口符合条件时,把起始索引加入 res
            if (valid == need.size())
                res.push_back(left);
            char d = s[left];
            left++;
            // 进行窗口内数据的一系列更新
            if (need.count(d)) {
                if (window[d] == need[d])
                    valid--;
                window[d]--;
            }
        }
    }
    return res;
}

借鉴leetcode
作者:labuladong

 

 

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-03-11 21:44:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-11 21:44:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-11 21:44:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-11 21:44:06       18 阅读

热门阅读

  1. 行为型模式

    2024-03-11 21:44:06       18 阅读
  2. 738. 单调递增的数字

    2024-03-11 21:44:06       22 阅读
  3. sqoop-import 详解

    2024-03-11 21:44:06       20 阅读
  4. 最多几个直角三角形python

    2024-03-11 21:44:06       21 阅读
  5. Node docker 容器部署及配置参数

    2024-03-11 21:44:06       20 阅读
  6. 用户登录问题——登录态

    2024-03-11 21:44:06       18 阅读
  7. 算法补习基础完整版

    2024-03-11 21:44:06       15 阅读
  8. LeetCode解法汇总2129. 将标题首字母大写

    2024-03-11 21:44:06       18 阅读
  9. 【SQL实用技巧】-- 分组内求topN问题

    2024-03-11 21:44:06       18 阅读
  10. 全方位理解架构

    2024-03-11 21:44:06       20 阅读