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

LeetCode100之找到字符串中所有字母异位词(438)--Java

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" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

        提示

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

        难度等级

        中等

        题目链接

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

2.解题思路

        这道题要我们找出s字符串中p的所有字母异位词,首先我们可以知道的就是,既然是要找p的字母异位词,那我们从s中找的子串长度就必须和p一样,那么我们也就可以向排除一些情况,那就是如果s的长度比p的长度还小,那s中就不可能有p的字母异位词了。

        //获取字符串的长度int sLength = s.length();//窗口大小int pLength = p.length();//如果s的长度小于p的长度,s中不可能有p的字母异位词if(sLength < pLength){return new ArrayList<>();}

        接着,因为p的长度是固定的,我们要在s中寻找p长度的子串,如果了解过滑动窗口的人,很容易就可以想到,我们可以用滑动窗口来寻找s中是p的字母异位词的子串,窗口的大小就是p的长度。

        由于字母异位词字符随便排序的问题,我们无法通过正常的比较来判断我们找到的子串是否为p的字母异位词,但是字母异位词无序但字母个数一定的这个特点给我们提供了突破口。我们可以通过比较p中各个字符出现的次数是否与我们在s中找到的子串的字符个数相等,是的话,我们找到的子串就是那个排序可能与p不同的字母异位词了。

        解决了如何找到字母异位词的思路之后,我们还有解决的一个问题就是用什么来存储字符出现个数的问题。我想大家对key-value的数据类型应该不陌生吧,我们可以使用key-value的结果来存储字符出现的个数,从而实现O(1)时间复杂度的增加和修改。提到key-value类型,大部分人应该第一时间就能想到用hashMap来存储。但是在这道题里面,可以不用hashMap来存储,可以直接使用数组来存储即可。由于题目告诉我们,s和p仅包含小写字母,也就数说顶天了也就只有26个字符,而且它们的ASCII码都是连续的,所以我们可以将字符减去第一个小写字母'a'的ASCII码,就可以将它们与数组的索引按顺序匹配起来,所以我们可以只有数据就来实现26个小写字母的key-value的统计。

        //初始化两个数组用于存储字母出现的次数int[] sArr = new int[26];int[] pArr = new int[26];

        创建完两个用于统计的数组之后,我们就可以开始初始化这两个数组了。将p从所有出现的字符统计到pArr(统计p的数组)中,并将s中前pLength(窗口大小)个字符统计到sArr(统计s子串的字符)中,这样我们就实现了两个统计数组的初始化了。我们再定义一个List集合用于存储所有的结果,我们的准备工作就做完了。

//存储异位词子串起始索引List<Integer> data = new ArrayList<>();//初始化两个数组(统计p中的字符个数并且统计s的前pLength个字符的个数)for(int i = 0;i < pLength;i++){sArr[s.charAt(i) - 'a']++;pArr[p.charAt(i) - 'a']++;}   

        接着,我们就可以来开始遍历s字符串了,因为我们已经统计了一部分字符串,所以我们可以先比较当前窗口中的子串是否和p是字母异位词,比较两个数组中各个字符的数量是否相等,是的话,则将窗口的起始索引(当前索引-窗口大小)存入List集合中。比较完之后,窗口开始向当前索引滑动,减去统计数组中窗口左边界的字符次数,因为它被滑出了,不在窗口之内了,然后再加上当前索引的字符的次数,因为窗口滑动后将它包含在内了。

         //比较两个窗口中字符出现的个数是否相等,是则为字母异位词if(Arrays.equals(sArr,pArr)){//i-窗口大小即为起始索引data.add(i - pLength);}//移动窗口,减去移动前左边界的字符sArr[s.charAt(i-pLength) - 'a']--;//加上移动后右边界的字符sArr[s.charAt(i) - 'a']++;

        不断的重复上述操作,知道窗口滑到s字符串的最右边为止。

        退出循环之后,最后比较一下窗口中的子串是否为p的字母异位词,因为最后一次滑动之后,不会再进入循环,所以最后一次滑动没有去判断是否为字母异位词,要给它不上。

        //最后再比较一次是否是字母异位词if(Arrays.equals(sArr,pArr)){data.add(sLength - pLength);}

        补上最后一次判断之后,就可以直接返回结果了。

3.代码展示

class Solution {public List<Integer> findAnagrams(String s, String p) {//获取字符串的长度int sLength = s.length();//窗口大小int pLength = p.length();//如果s的长度小于p的长度,s中不可能有p的字母异位词if(sLength < pLength){return new ArrayList<>();}//初始化两个数组用于存储字母出现的次数int[] sArr = new int[26];int[] pArr = new int[26];//存储异位词子串起始索引List<Integer> data = new ArrayList<>();//初始化两个数组(统计p中的字符个数并且统计s的前pLength个字符的个数)for(int i = 0;i < pLength;i++){sArr[s.charAt(i) - 'a']++;pArr[p.charAt(i) - 'a']++;}   //开始遍历(从pLength开始)for(int i = pLength;i < sLength;i++){//比较两个窗口中字符出现的个数是否相等,是则为字母异位词if(Arrays.equals(sArr,pArr)){//i-窗口大小即为起始索引data.add(i - pLength);}//移动窗口,减去移动前左边界的字符sArr[s.charAt(i-pLength) - 'a']--;//加上移动后右边界的字符sArr[s.charAt(i) - 'a']++;}//最后再比较一次是否是字母异位词if(Arrays.equals(sArr,pArr)){data.add(sLength - pLength);}return data;}}

4.总结

        这道题的难点主要在于能不能想到用字符的个数是否相等来判断是否为字母异位词,至于用什么数据结构来存储字母的个数,其实都可以,只是用数组比直接用hashMap更加节省空间罢了,直接用hashMap也可以解决这道题,差别不是很大。好了,今天这道题就啰嗦到这里了,祝大家早日拿到offer!

相关文章:

LeetCode100之找到字符串中所有字母异位词(438)--Java

1.问题描述 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 示例1 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 …...

【Python】Python自习课:第一个python程序

【Python】Python自习课&#xff1a;第一个python程序...

DICOM标准:解析DICOM属性中的病人模块

目录 病人模块概述 1. 病人关系模块&#xff08;Patient Relationship Module&#xff09; 2. 病人识别模块&#xff08;Patient Identification Module&#xff09; 3. 病人统计模块&#xff08;Patient Demographic Module&#xff09; 4. 病人医学模块&#xff08;Pati…...

C++设计模式创建型模式———生成器模式

文章目录 一、引言二、生成器/建造者模式三、总结 一、引言 上一篇文章我们介绍了工厂模式&#xff0c;工厂模式的主要特点是生成对象。当对象较简单时&#xff0c;可以使用简单工厂模式或工厂模式&#xff1b;而当对象相对复杂时&#xff0c;则可以选择使用抽象工厂模式。 工…...

基于微信小程序的校园失物招领系统的研究与实现(V4.0)

博主介绍&#xff1a;✌stormjun、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…...

DDRNet模型创新实现人像分割

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【BiLSTM模型实现电力数据预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…...

try…catch…finally语句里return语句的执行顺序是怎样的?

第一种情况 try语句块里面有return语句&#xff0c;catch语句块和finally语句块里面没有return语句。 代码如下&#xff1a; public class Main {public static void main(String[] args) {System.out.println(test1());}public static int test1() {int i 10;try {System.o…...

AIGC与虚拟现实(VR)的结合与应用前景

公主请阅 引言1. AIGC与VR的基本概念1.1 AIGC简介1.2 VR技术概述 2. AIGC在VR中的应用2.1 生成虚拟环境2.2 自动生成内容2.3 互动体验 3. AIGC与VR结合的应用案例3.1 教育培训3.2 娱乐与游戏3.3 心理治疗3.4 虚拟旅游 4. AIGC与VR结合的挑战4.1 技术限制4.2 用户体验4.3 数据隐…...

如何在visual studio中 生成 并 使用dll和lib文件

因为工作需求&#xff0c;要写lib和dll给别人使用。 使用visual studio2022 以函数 int getmyset() { return 0;} 为例子 首先 点击打开 visual studio 文件->新建->项目 选择windows桌面向导 选择应用程序类型为动态链接库.dll 分别创建MyDLL.h和MyDLL.cpp文件&a…...

「Mac畅玩鸿蒙与硬件15」鸿蒙UI组件篇5 - Slider 和 Progress 组件

Slider 和 Progress 是鸿蒙系统中的常用 UI 组件。Slider 控制数值输入,如音量调节;Progress 显示任务的完成状态,如下载进度。本文通过代码示例展示如何使用这些组件,并涵盖 进度条类型介绍、节流优化、状态同步 和 定时器动态更新。 关键词 Slider 组件Progress 组件节流…...

Iceoryx2:高性能进程间通信框架(中间件)

文章目录 0. 引言1. 主要改进2. Iceoryx2 的架构3. C示例代码3.1 发布者示例&#xff08;publisher.cpp&#xff09;3.2 订阅者示例&#xff08;subscriber.cpp&#xff09; 4. 机制比较5. 架构比较6. Iceoryx vs Iceoryx2参考资料 0. 引言 Iceoryx2 是一个基于 Rust 实现的开…...

构 造 器

我们创建了一个对象&#xff0c;在其中定义了属性&#xff0c;new一个对象&#xff0c;然后设置对应的属性&#xff0c;但是我们可以在new对象的时候&#xff0c;同时传入我们要设置的属性&#xff0c;这个时候就需要构造器。 特点 构造方法是一个特殊的成员方法&#xff0c;…...

草莓叶片病害识别与分类数据集(猫脸码客 第234期)

草莓叶片病害识别与分类数据集 草莓作为一种重要的经济作物&#xff0c;在全球范围内广泛种植。然而&#xff0c;草莓生产过程中常常受到各种病害的困扰&#xff0c;其中叶片病害尤为严重。为了有效识别、检测和分类草莓叶片病害&#xff0c;构建一个高质量的数据集是至关重要…...

微服务设计模式 - 断路器模式 (Circuit Breaker Pattern)

微服务设计模式 - 断路器模式 (Circuit Breaker Pattern) 定义 断路器模式&#xff08;Circuit Breaker Pattern&#xff09;是云计算和微服务架构中的一种保护性设计模式&#xff0c;其目的是避免系统中的调用链出现故障时&#xff0c;导致系统瘫痪。通过断路器模式&#xff…...

HarmonyOS NEXT 应用开发实战(九、知乎日报项目详情页实现详细介绍)

在本篇博文中&#xff0c;我们将探讨如何使用 HarmonyOS Next 框架开发一个知乎日报的详情页&#xff0c;逐步介绍所用到的组件及代码实现。知乎日报是个小巧完整的小项目&#xff0c;这是一个循序渐进的过程&#xff0c;适合初学者和有一定开发经验的工程师参考。 1. 项目背景…...

lvgl 模拟器移植(V9)

1.模拟器代码下载 1.1&#xff1a;通过git 下载 github链接&#xff1a;GitHub - lvgl/lv_port_pc_visual_studio: Visual Studio projects for LVGL embedded graphics library. Recommended on Windows. Linux support with Wayland is work in progress.https://github.com…...

基于vue+neo4j 的中药方剂知识图谱可视化系统

前言 历时一周时间&#xff0c;中药大数据R02系统中药开发完毕&#xff0c;该系统通过scrapy工程获取中药数据&#xff0c;使用python pandas预处理数据生成知识图谱和其他相关数据&#xff0c;利用vuespringbootneo4jmysql 开发系统&#xff0c;具体功能请看本文介绍。 简要…...

(自用)机器学习python代码相关笔记

一些自存的机器学习函数和详细方法记录&#xff0c;欢迎指错。 前言&#xff1a;读取数据方法 import pandas as pd import pandas as pddf pd.read_csv(数据集.csv, header0) # header是从哪一行开始读起&#xff0c;一般是0&#xff0c;也可以取infer 一、数据处理&#…...

docker复现pytorch_cyclegan

1、安装docker 配置docker镜像 添加镜像源至docker engine 2、wsl2安装nvidia-docker 要在Ubuntu中安装NVIDIA Docker&#xff0c;需要满足以下条件&#xff1a; 确保主机已安装NVIDIA的CUDA驱动程序&#xff0c;并使用适用于您操作系统的正确版本。 wsl --update在Ubuntu…...

IDEA2024下安装kubernetes插件并配置进行使用

【1】安装插件 其实2024.2.3下默认已经安装了kubernetes插件&#xff0c;如果你发现自己IDEA中没有&#xff0c;在市场里面检索并下载即可。 【2】kubernetes配置 ① 前置工作 首先你要准备一个config文件和一个kubectl.exe 。 config文件类似如下&#xff1a; apiVersi…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...