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

[Java恶补day9] 438.找到字符串中所有字母异位词

给定两个字符串 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 ∗ 10 4 3 * 10^4 3104
s 和 p 仅包含小写字母


知识点:
定长滑动窗口、数组、字符串


解:
这道题有多种实现方式:①定长滑动窗口;②不定长滑动窗口。这里实现的是①定长滑动窗口。
核心思想是:统计字符的出现次数,若s的子串、p中的所有字符的出现次数相同,则当前滑动窗口内的子串是异位词。

首先,获取两个字符串长度,提高后续代码的可读性。

然后,这里定义了两个数组,分别存储字符串s、p中各个字符的出现次数,因此数组大小分别是26,记录所有字母(26个)。使用数组而不是前面题目使用的HashMap,因为要对元素在或不在Map中进行分类讨论,没有数组的操作简单便利。

接着,若字符串s的长度<字符串p的长度,则必不存在异位词,因为无法从s中找到一个比自身还长的子串。

然后,遍历p的每个字符,统计各个字符的出现次数:cntP[p.charAt(i) - 'a']++;

然后,遍历s的每个字符,这里用滑动窗口右边界,控制滑动窗口的内容。这里的核心思路是:
获取当前滑动窗口的左边界,用start表示。因为是定长,所以右边界end-n+1即为左边界的下标。
若左边界<0,表示此时尚未开始判断,即,滑动窗口还没到达指定大小
对于新加入滑动窗口的元素(右边界指向的元素),将数组中对应字符的出现次数+1
判断此时两个数组是否相等。若相等,表明当前滑动窗口内的子串、p中各个字符的出现次数是相同的,因此当前滑动窗口内的子串就是异位词。
更新滑动窗口,对于离开滑动窗口的元素(左边界指向的元素),将数组中对应字符的出现次数-1

时间复杂度:O(∣Σ∣m)。Arrays.equals()时间复杂度是O(∣Σ∣),总共遍历m个元素。
空间复杂度:O(∣Σ∣)。因为两个数组各存储了26个字母
∣Σ∣=包含的字符的数量

class Solution {public List<Integer> findAnagrams(String s, String p) {//核心:定长滑动窗口,统计字母的出现次数,若s、p的字母出现次数相同,则是异位词List<Integer> res = new ArrayList<>();//获取字符串s、p的长度int m = s.length();int n = p.length();//定义数组,存储字符的出现次数(比HashMap的操作更方便)int[] cntS = new int[26];int[] cntP = new int[26];//特殊情况判断,直接返回空列表if (m < n)return res;//统计p的每个字符的出现次数for (int i = 0; i < n; i++) {cntP[p.charAt(i) - 'a']++;}//用滑动窗口右边界控制子串for (int end = 0; end < m; end++) {//获取滑动窗口左边界int start = end - n + 1;//新加入滑动窗口的元素(end指向的元素):出现次数+1cntS[s.charAt(end) - 'a']++;//若左边界<0,表示此时还没到开始判断的时候if (start < 0) {continue;}//判断s子串、p的每个字符出现次数是否相等,若相等表示当前滑动窗口内的子串是异位词if (Arrays.equals(cntS, cntP)) {res.add(start);//将异位词的起始下标加入结果列表}//更新滑动窗口,离开滑动窗口的元素(start指向的元素):出现次数-1cntS[s.charAt(start) - 'a']--;}return res;}
}

参考:
1、灵神解析

相关文章:

  • 202505系分论文《论信息系统开发方法及应用》
  • 决胜2025:企业级BI产品深度评测与选型指南
  • pip国内镜像源配置
  • 数值积分实验
  • el-table配置表头固定而且高度变化
  • Linux下基本指令的介绍
  • 【芯片设计- SoC 常用模块 9.1 -- PLL 介绍】
  • Redis集群大Key问题深度解决方案
  • 深入解析 IP 代理:原理、应用场景与优化策略
  • 操作系统导论 第37章:磁盘驱动器
  • 脑机新手指南(一):BCILAB 脑机接口工具箱新手入门指南
  • 面试高频图论题『墙与门』:Swift BFS 解法全流程拆解
  • STM32学习第一课--工程建立(云端备份与自我复盘)
  • 回归任务损失函数对比曲线
  • git 一台电脑一个git账户,对应多个仓库ssh
  • 将can日志数据提取到excle中
  • 4. Qt对话框(1)
  • C语言Day9:C语言类型转换规则
  • ADVANTEST D3286 Error Detector OPeration Manual 爱德万测试
  • CVE-2017-12629-XXE源码分析与漏洞复现
  • 汉口做网站公司/网络销售怎么找客源
  • 南通建设工程信息网官网/魔贝课凡seo课程好吗
  • wordpress同城插件/西安seo排名优化推广价格
  • 做网站分为哪几个岗位/商业计划书
  • 做佩戴护身符的厂家网站/无锡网站制作
  • 学校网站建设介绍/互联网营销的方式有哪些