leetcode hot100【LeetCode 438. 找到字符串中所有字母的异位词】java实现

LeetCode 438. 找到字符串中所有字母的异位词

题目描述

给定两个字符串 sp,找到 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 * 10^4
  • sp 仅包含小写字母

Java 实现代码

java 复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLength = s.length();
        int pLength = p.length();
        if (sLength < pLength) {
            return new ArrayList<>();
        }
        int[] sArr = new int[26];
        int[] pArr = new int[26];
        List<Integer> data = new ArrayList<>();
        for (int i = 0; i < pLength; i++) {
            sArr[s.charAt(i) - 'a']++;
            pArr[p.charAt(i) - 'a']++;
        }
        for (int i = pLength; i < sLength; i++) {
            if (Arrays.equals(sArr, pArr)) {
                data.add(i - pLength);
            }
            int left = i - pLength;
            int right = i;
            sArr[s.charAt(left) - 'a']--;
            sArr[s.charAt(right) - 'a']++;
        }
        if (Arrays.equals(sArr, pArr)) {
            data.add(sLength - pLength);
        }
        return data;
    }
}

解题思路

  1. 初始化 :创建两个长度为 26 的数组 sArrpArr,分别用于存储字符串 sp 中每个字符的出现次数。
  2. 填充 pArr :遍历字符串 p,统计每个字符的出现次数。
  3. 滑动窗口 :使用两个指针 leftright 表示窗口的边界,right 指针向右移动扩展窗口。
  4. 更新 sArr :当 right 指针移动时,将新进入窗口的字符的计数加一。
  5. 检查异位词 :如果当前窗口的字符计数与 p 相同,则说明找到了一个异位词,记录下 left 指针的索引。
  6. 移动 left 指针 :当窗口大小超过 p 的长度时,移动 left 指针,减少离开窗口的字符的计数。
  7. 返回结果:最终返回所有找到的异位词子串的起始索引。

复杂度分析

  • 时间复杂度 :O(n),其中 n 是字符串 s 的长度。每个字符只被访问两次(一次由 right 指针,一次由 left 指针)。
  • 空间复杂度:O(1),使用固定大小的数组存储字符计数,不依赖于输入大小。
相关推荐
玖玥拾12 分钟前
LeetCode 202 快乐数
算法·leetcode
LuminousCPP15 分钟前
数据结构-二叉树(六):BFS层序遍历与完全二叉树判断|复用链式队列 + (N_0=N_2+1) 性质证明
c语言·数据结构·笔记·算法·二叉树·宽度优先
源码宝21 分钟前
SpringBoot+Vue2 诊所门诊管理系统,完整前后端源码,可直接部署上线
java·源码·his系统·门诊系统·程序代码·诊所系统·门诊his
yychen_java23 分钟前
九:Text-to-SQL 智能数据查询与 Human-in-the-Loop 人机协作
java·人工智能·架构
ZhouDevin1 小时前
算法论文/数据集3——CLD(TMLR2025)压缩训练集,仅保留对验证集有益的样本
人工智能·深度学习·算法·计算机视觉
Tim_102 小时前
【LeetCode】29、两数相除
算法·leetcode·职场和发展
lhldsg2 小时前
智慧场馆解决方案小程序开发实战:从架构设计到部署指南
java·小程序·uni-app
Freak嵌入式2 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活
船厂电气自动化ai大模型2 小时前
AI大模型与数学/第63课:矩阵定义、矩阵加法、标量乘法(逐级精讲)
数据结构·人工智能·深度学习·线性代数·算法
余额瞒着我当琳3 小时前
算法修炼 chapter 2 双指针进阶、盛最多水的容器、有效三角形的个数、两数之和、三数之和、四数之和
算法