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

一题目链接

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

二题目描述

三解法(滑动窗口 + 哈希表)

3.1算法思路:

◦ 因为字符串 p 的异位词的长度一定与字符串 p 的长度相同,所以我们可以在字符串 s 中构
造一个长度为与字符串 p 的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;
◦ 当窗口中每种字母的数量与字符串 p 中每种字母的数量相同时,则说明当前窗口为字符串 p
的异位词;
◦ 因此可以用两个大小为 26 的数组来模拟哈希表,一个来保存 s 中的子串每个字符出现的个
数,另一个来保存 p 中每一个字符出现的个数。这样就能判断两个串是否是异位词。

3.2C++ 算法代码:

cpp 复制代码
class Solution
{
    public:
        vector<int> findAnagrams(string s, string p)
        {
            vector<int> ret;
            int hash1[26] = { 0 }; // 统计字符串 p 中每个字符出现的个数
            for(auto ch : p) hash1[ch - 'a']++;
            int hash2[26] = { 0 }; // 统计窗口里面的每一个字符出现的个数
            int m = p.size();
            for(int left = 0, right = 0, count = 0; right < s.size(); right++)
            {
                char in = s[right];
                // 进窗口 + 维护 count
                if(++hash2[in - 'a'] <= hash1[in - 'a']) count++;
                if(right - left + 1 > m) // 判断
                {
                    char out = s[left++];
                    // 出窗口 + 维护 count
                    if(hash2[out - 'a']-- <= hash1[out - 'a']) count--;
                }
                // 更新结果
                if(count == m) ret.push_back(left);
             }
            return ret;
        }
};

3.2.1C++结果

3.3Java 算法代码:

java 复制代码
class Solution
{
    public List<Integer> findAnagrams(String ss, String pp)
    {
        List<Integer> ret = new ArrayList<Integer>();
        char[] s = ss.toCharArray();
        char[] p = pp.toCharArray();
        int[] hash1 = new int[26]; // 统计字符串 p 中每一个字符出现的个数
        for(char ch : p) hash1[ch - 'a']++;
        int[] hash2 = new int[26]; // 统计窗口中每一个字符出现的个数
        int m = p.length;
        for(int left = 0, right = 0, count = 0; right < s.length; right++)
        {
            char in = s[right];
            // 进窗口 + 维护 count
            if(++hash2[in - 'a'] <= hash1[in - 'a']) count++;
            if(right - left + 1 > m) // 判断
            {
                char out = s[left++];
                // 出窗口 + 维护 count
                if(hash2[out - 'a']-- <= hash1[out - 'a']) count--;
            }
            // 更新结果
            if(count == m) ret.add(left);
        }
        return ret;
    }
}

3.3.2Java结果

四细节与避坑

  1. 边界处理 :如果 p.size() > s.size(),直接返回空数组,避免越界。
  2. 数组对比 :用 memcmp 直接对比两个 26 元素的数组,比循环判断更高效。
  3. 窗口滑动逻辑
    • 左边界索引:i - n2
    • 新窗口起始索引:i - n2 + 1
  4. 内存优化:全程不用创建子串,只用两个 26 大小的数组,空间复杂度 O (1),不会超内存。
相关推荐
碧海银沙音频科技研究院9 分钟前
8基于BES2700IHC数字助听器系统开发
嵌入式硬件·算法
HZZD_HZZD44 分钟前
智能电表选CoAP还是MQTT?合众致达万表实测:CoAP省流17.3%、续航提升38%,附报文拆解与选型矩阵
算法
linux-hzh1 小时前
百日算法修炼 · Day 05
java·算法
paopaokaka_luck1 小时前
基于springboot3+vue3的云南本土影视文旅推荐平台(协同过滤算法、Echarts图形化分析)
前端·spring boot·学习·算法·echarts·mybatis
程序员-Benothing1 小时前
MySQL 的存储引擎有哪些?它们之间有什么区别?
后端·mysql·面试·职场和发展
Ivanqhz2 小时前
泰勒展开(Taylor Expansion)
算法·决策树·机器学习·集成学习
zander2583 小时前
34. 在排序数组中查找元素的第一个和最后一个位置:用两个边界定位区间
数据结构·算法·leetcode
郑州光合科技余经理8 小时前
代驾系统架构拆解:订单链路、权限组织与私有化源码交付
开发语言·后端·算法·架构·系统架构·uni-app·php
To_OC10 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
天才测试猿10 小时前
2026软件测试面试八股文(含答案+文档)
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展