当前位置: 首页 > article >正文

【练习】【滑动窗口】力扣热题100 438. 找到字符串中所有字母异位词

题目

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

给定两个字符串 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” 的异位词。

来源:力扣热题100 438. 找到字符串中所有字母异位词


思路(注意事项)

数据量较大时,用数组记录滑动窗口 字母出现的频率 比哈希表效率高一些


纯代码1(哈希表)

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        unordered_map<char,int> p_count, s_count;

        for (int i = 0; i < p.size(); i ++) p_count[p[i]] ++;
        for (int i = 0; i < p.size() - 1; i ++) s_count[s[i]] ++;

        for (int i = p.size() - 1; i < s.size();  i ++)
        {
            s_count[s[i]] ++;
            if (p_count == s_count) ans.push_back(i - p.size() + 1); 
            s_count[s[i - p.size() + 1]] --;
            if (s_count[s[i - p.size() + 1]] == 0) s_count.erase (s[i - p.size() + 1]);
        } 

        return ans;
    }
};

题解1(加注释)

class Solution {
public:
    // 该函数用于在字符串 s 中找出所有字符串 p 的异位词的起始索引
    std::vector<int> findAnagrams(std::string s, std::string p) {
        // 用于存储所有满足条件的异位词的起始索引
        std::vector<int> ans;
        // 用于统计字符串 p 中每个字符的出现次数
        std::unordered_map<char, int> p_count;
        // 用于统计当前滑动窗口内字符串 s 中每个字符的出现次数
        std::unordered_map<char, int> s_count;

        // 遍历字符串 p,统计其中每个字符的出现次数
        for (int i = 0; i < p.size(); i++) {
            p_count[p[i]]++;
        }

        // 初始化滑动窗口,先统计字符串 s 中前 p.size() - 1 个字符的出现次数
        for (int i = 0; i < p.size() - 1; i++) {
            s_count[s[i]]++;
        }

        // 开始移动滑动窗口,从第 p.size() - 1 个位置开始,直到字符串 s 的末尾
        for (int i = p.size() - 1; i < s.size(); i++) {
            // 将当前字符 s[i] 加入到滑动窗口中,并更新其出现次数
            s_count[s[i]]++;

            // 比较当前滑动窗口内字符的出现次数 s_count 和字符串 p 中字符的出现次数 p_count
            // 如果两者相等,说明当前滑动窗口内的字符串是 p 的异位词
            if (p_count == s_count) {
                // 计算当前异位词在字符串 s 中的起始索引,并添加到结果向量 ans 中
                ans.push_back(i - p.size() + 1);
            }

            // 将滑动窗口的最左侧字符移除,并更新其出现次数
            s_count[s[i - p.size() + 1]]--;

            // 如果该字符的出现次数变为 0,从 s_count 中删除该字符,避免不必要的比较
            if (s_count[s[i - p.size() + 1]] == 0) {
                s_count.erase(s[i - p.size() + 1]);
            }
        }

        // 返回存储所有满足条件的起始索引的向量 ans
        return ans;
    }
};

纯代码2(数组)


class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans, p_count(26), s_count(26);
        if (p.size() > s.size()) return ans;        
        
        for (int i = 0; i < p.size(); i ++) p_count[p[i] - 'a'] ++;
        for (int i = 0; i < p.size() - 1; i ++) s_count[s[i] - 'a'] ++;

        for (int i = p.size() - 1; i < s.size();  i ++)
        {
            s_count[s[i] - 'a'] ++;
            if (p_count == s_count) ans.push_back(i - p.size() + 1); 
            s_count[s[i - p.size() + 1] - 'a'] --;
        } 

        return ans;
    }
};

题解2(加注释)

class Solution {
public:
    // 该函数用于在字符串 s 中找出所有字符串 p 的异位词的起始索引
    std::vector<int> findAnagrams(std::string s, std::string p) {
        // ans 用于存储找到的异位词在字符串 s 中的起始索引
        std::vector<int> ans;
        // p_count 是一个长度为 26 的数组,用于统计字符串 p 中每个小写字母的出现次数
        // 数组索引 0 - 25 分别对应字母 'a' - 'z'
        std::vector<int> p_count(26);
        // s_count 同样是长度为 26 的数组,用于统计当前滑动窗口内字符串 s 中每个小写字母的出现次数
        std::vector<int> s_count(26);

        // 如果字符串 p 的长度大于字符串 s 的长度,那么 s 中不可能存在 p 的异位词,直接返回空数组
        if (p.size() > s.size()) return ans;

        // 遍历字符串 p,统计其中每个小写字母的出现次数
        // 通过字符减去 'a' 得到对应的数组索引,比如 'a' - 'a' 得到 0,'b' - 'a' 得到 1 以此类推
        for (int i = 0; i < p.size(); i++) {
            p_count[p[i] - 'a']++;
        }

        // 初始化滑动窗口,统计字符串 s 中前 p.size() - 1 个字符里每个小写字母的出现次数
        for (int i = 0; i < p.size() - 1; i++) {
            s_count[s[i] - 'a']++;
        }

        // 开始移动滑动窗口,从第 p.size() - 1 个位置开始,直到字符串 s 的末尾
        for (int i = p.size() - 1; i < s.size(); i++) {
            // 将当前字符 s[i] 加入到滑动窗口中,并更新对应字母的出现次数
            s_count[s[i] - 'a']++;

            // 比较当前滑动窗口内每个小写字母的出现次数(s_count)和字符串 p 中每个小写字母的出现次数(p_count)
            // 如果两个数组相等,说明当前滑动窗口内的字符串是 p 的异位词
            if (p_count == s_count) {
                // 计算当前异位词在字符串 s 中的起始索引,并添加到结果数组 ans 中
                ans.push_back(i - p.size() + 1);
            }

            // 将滑动窗口的最左侧字符移除,并更新对应字母的出现次数
            s_count[s[i - p.size() + 1] - 'a']--;
        }

        // 返回存储所有满足条件的起始索引的数组 ans
        return ans;
    }
};

http://www.kler.cn/a/552589.html

相关文章:

  • 从插入排序到希尔排序
  • A与B组件自动对齐与组装,无映射直接补偿。
  • SpingBoot-Vue 前后端分离—实现钉钉免登功能(2025)
  • 【Spring+MyBatis】_图书管理系统(中篇)
  • c# -01新属性-模式匹配、弃元、析构元组和其他类型
  • spark大数据分析
  • python-leetcode-最小路径和
  • vue中使用富文本编辑器
  • SpringBoot速成(14)文件上传P23-P26
  • GIT:如何合并已commit的信息并进行push操作
  • 【达梦数据库】dblink连接[SqlServer/Mysql]报错处理
  • Edge浏览器清理主页
  • Copilot Next Edit Suggestions(预览版)
  • nodejs:express + js-mdict 网页查询英汉词典,能显示图片
  • 【Java 面试 八股文】并发编程篇
  • The First项目报告:重塑链上游戏生态,解读B3 Base的双赢局面
  • Pytorch实现之粒子群优化算法在GAN中的应用
  • 一周学会Flask3 Python Web开发-post请求与参数获取
  • TCP通讯-客户端链接
  • mysql 学习16 视图,存储过程,存储函数,触发器