leetcode 30. 串联所有单词的子串(优质解法)

news2024/10/7 15:26:13

代码:

class Solution {
    public static List<Integer> findSubstring(String s, String[] words) {
        List<Integer> integerList=new ArrayList<>();

        int length=words.length;    //words 数组中的字符串个数
        int size=words[0].length(); //words 数组中每个字符串的长度

        HashMap<String,Integer> hashMap1=new HashMap<>();   //存储 words 数组中字符串以及出现的个数


        //把 words 数组中字符串以及出现的个数保存到 hashMap1 中
        for(String str:words){
            hashMap1.put(str,hashMap1.getOrDefault(str,0)+1);
        }

        for(int i=0;i<size;i++){
            int count=0;    //记录当前子串中符合条件的字符串
            HashMap<String,Integer> hashMap2=new HashMap<>();   //存储讨论的子串中字符串以及出现的个数
            for(int left=i,right=i;right+size<=s.length();right+=size){
                //把 right 指针指向的数据入窗口
                String in=s.substring(right,right+size);
                hashMap2.put(in,hashMap2.getOrDefault(in,0)+1);

                //判断当前入窗口的字符串是否是符合条件的
                if(hashMap2.get(in)<=hashMap1.getOrDefault(in,0)){
                    count++;
                }

                //判断当前子串的长度是否过长,是否需要出窗口
                if(right-left+1>length*size){
                    String out=s.substring(left,left+size);
                    //判断出窗口的字符串是否是有效字符串
                    if(hashMap2.get(out)<=hashMap1.getOrDefault(out,0)){
                        count--;
                    }
                    hashMap2.put(out,hashMap2.get(out)-1);
                    left+=size;
                }

                //判断有效字符串个数是否符合条件
                if(count==length){
                    integerList.add(left);
                }
            }
        }
        return integerList;
    }
}

题解:

        本题的含义表达得很明确,我们需要在字符串 s 中找到一个子串,子串由字符串数组 words 中的字符串以不同顺序组成

        我们首先可以想到一个暴力解法,遍历出字符串 s 中的所有子串,找出完全由 words 中的字符串以不同顺序组成的子串。现在就涉及到一个问题,我们如何知道子串是完全由 words 中的字符串以不同顺序组成的

        我们可以利用哈希表 hash1 和 hash2 存储 words 数组中和子串中字符串的相关信息,以字符串为 key ,个数为 value ,然后比对 hash1 和 hash2 中的内容,便知道当前子串是否是符合条件的

        假设输入:s = "barfoothefoobar", words = ["foo","bar"]

        首先我们可以获得的信息是,words 数组中的字符串个数 length = 2,每个字符串的大小 size = 3 ,由于我们要遍历所有的子串,所以让 L 和 R 指针指向下标为 0 的位置。我们将 words 数组中的相关信息保存到哈希表 hash1 中,foo-1,bar-1用变量 count 记录子串中有效字符串的个数

          因为符合要求的子串是由 words 数组中的字符串按不同顺序组成的,而 words 数组中的字符串是 3 个字符为一个整体,所以我们在寻找子串的时候也以 3 个字符为一个整体,R 指针指向当前位置,通过 s.substring(right,right+size) 取出字符串 bar,将 bar - 1 保存到 hash2 中,由于在hash1 中 bar-1,只要子串中的字符个数小于等于 wors 数组中对应字符的个数,就代表该字符是有效字符,所以 bar 是有效字符,此时 count++,count=1

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r      

L

R

     录入字符串 bar 的信息以后,R 指针向右移动 size 位,录入下一个字符串 foo,将 foo- 1 保存到 hash2 中,由于在hash1 中 foo-1,,所以 foo 是有效字符,此时 count++,count=2,因为此时子串为 barfoo 长度为 6 == size*length ,并且 count == 2 == length,所以该子串是符合要求的,我们就直接记录 L 指针指向的下标 0

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r      

L

                             R  

        当 R 指针再向右移 size 位以后,子串为 barfoothe,大小为 9 > size * length ,字符数都比 words 数组中的字符数多了,肯定不符合要求,代表以 L 指针为首的子串已经讨论完毕,让 L 指针向右移动 size 位,讨论下一组字符串

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r           

L

                                                           R        

        L 指针之前指向的是字符串 bar ,bar 在 hash2 中的个数为 1,小于等于在 hash1 中的个数,所以是有效字符串,因此在将 L 指针移动前,我们需要修改 hash2 中的 bar - 0,count = 1,

此时子串的长度符合要求,但是有效字符串个数 count < length,所以该子串不符合要求,让 R 指针向右移动 size 位 

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r           

                              L  

                                                           R 

        之后循环上述操作即可

        有细心的小伙伴会发现,上面的流程没有讨论完所有的子串,我们还需要以如下的两种情况,继续上述的操作,也就是在上述的循环操作要执行 size 次

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r           

           L

           R

    

b        a        r        f        o        o        t        h        e        f        o        o        b        a        r           

                    L

                    R

      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1307599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle数据库对SAP的支持

其实有时候&#xff0c;很多信息都已经整理好了&#xff0c;你只需要知道他在哪里就好&#xff0c;无需自己整理。 Oracle数据库对SAP的支持&#xff0c;可以从这个网页快速了解。 看前面的概述&#xff1a; Oracle 数据库是全球 SAP 客户中排名第一的数据库&#xff0c;拥有…

Spring上IOC之@EnableAspectJAutoProxy

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

初识人工智能,一文读懂贝叶斯优化和其他算法的知识文集(8)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【深度学习】PHP操作mysql数据库总结

一.PHP数据库的扩展分类 1.MySQL 扩展是针对 MySQL 4.1.3 或更早版本设计的&#xff0c;是 PHP 与 MySQL数据库交互的早期扩展。由于其不支持 MySQL 数据库服务器的新特性&#xff0c;且安全性差&#xff0c;在项目开发中不建议使用&#xff0c;可用 MySQLi 扩展代替。 2.MySQ…

LeetCode 1457. 二叉树中的伪回文路径||位运算 DFS

1457. 二叉树中的伪回文路径 给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值的排列中&#xff0c;存在一个回文序列。 请你返回从根到叶子节点的所有路径中 伪回文 路径的…

记一次docker的overlay2目录占用大量磁盘空间

1、报错 Linux服务器报错磁盘没空间了&#xff1a; no space left on device2、排错 从根目录看下哪个目录有问题&#xff1a; cd / du -sh * # s即只显示总和&#xff0c;h即显示人类可读格式&#xff0c;就是数字单位的格式目录有点多&#xff0c;sort排序下&#xff1a;…

数学learning

目录 移动平均 简单移动平均 加权移动平均 指数移动平均 矩阵求导 矩阵对标量求导 Matrix-by-scalar 标量对矩阵求导 Scalar-by-matrix 参考博客 移动平均 优化算法里面会涉及到一个知识点&#xff1a;指数移动平均。 但是为了知识的完整性&#xff0c;这里会将常见的移动…

容器技术与操作系统

文章目录 容器技术 vs 虚拟机操作系统容器 Docker与操作系统 容器技术 vs 虚拟机 操作系统 操作系统是一个很重而且很笨的程序&#xff0c;简称笨重&#xff0c;有多笨重呢&#xff1f; 操作系统运行起来是需要占用很多资源的&#xff0c;大家对此肯定深有体会&#xff0c;刚…

ARM day8

1.题目&#xff1a;主机获取从机里面的温湿度数据&#xff0c;并打印出来 结果&#xff1a; 代码&#xff1a; main.c #include "iic.h"#include "si7006.h"void delay(int ms){int i,j;for(i0;i<ms;i){for(j0;j<2000;j);}}int main(){short tem;…

【Linux】锁的简单封装以及原理解析

文章目录 一、锁的原理过程1&#xff1a;过程2过程3过程4 二、 锁的简单封装1.LockGuard.hpp2.使用1.正常锁的使用2.使用封装后的 总结 一、锁的原理 为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条…

基于ssm社区管理与服务的设计与实现论文

目录 摘 要 1 Abstract 2 第一章 绪论 3 1.1研究背景 3 1.2 研究现状 3 1.3 研究内容 4 第二章 系统关键技术 5 2.1 Java简介 5 2.2 MySql数据库 5 2.3 B/S结构 6 2.4 Tomcat服务器 6 第三章 系统分析 7 3.1可行性分析 7 3.1.1技术可行性 7 3.1.2经济可行性 7 3.1.3运行可行性…

IP代理检测:判断IP质量优劣要注意的5件事

使用代理是各种在线活动的常见做法&#xff0c;但确保其质量对于避免潜在问题并确保无缝体验至关重要。 在本文中&#xff0c;我们深入探讨进行彻底代理检查以保证可靠性和安全性的基本方面。 1. 验证地理位置信息 评估代理时的主要考虑因素之一是其地理位置&#xff0c;这也…

自动化补丁管理软件

什么是自动化补丁管理 自动补丁管理&#xff08;或自动补丁&#xff09;是指整个补丁管理过程的自动化&#xff0c;从扫描网络中的所有系统到检测缺失的补丁&#xff0c;在一组测试系统上测试补丁&#xff0c;将它们部署到所需的系统&#xff0c;并提供定期更新和补丁部署状态…

RocketMQ如何保证消息的可靠性传递❓

RocketMQ 通过一系列的机制来保证消息的可靠性传递&#xff0c;确保在面对各种异常和故障情况时&#xff0c;消息系统能够稳定地处理和传递消息。以下是 RocketMQ 保证可靠性传递的关键机制&#xff1a; 1. 同步双写机制 (Synchronous Write Mechanism): RocketMQ的同步双写机…

oracle 拼接语句怎么写?

||的妙用&#xff0c;字符串和变量列名之间都得用||分隔&#xff0c;oracle等数据库两个单引号输出一个单引号&#xff0c;因为如果只写了一个的话 他会和最近的单引号被数据库认为是组成了一个空字符串&#xff0c;因此需要用两个单引号来表示这是个单引号 查询列间用&#xf…

锂电池基础知识及管理方式总结

这两天在排查一个锂电池无法充电的问题&#xff0c;用的是电池管理芯片BQ25713&#xff0c;网上相关的资料也很少&#xff0c;查看数据手册时&#xff0c;里面也有很多术语参数等不是很理解&#xff0c;所以&#xff0c;在此对锂电池的基础知识做个简单的总结&#xff0c;方面后…

算法:有效的括号(入栈出栈)

时间复杂度 O(n) 空间复杂度 O(n∣Σ∣)&#xff0c;其中 Σ 表示字符集&#xff0c;本题中字符串只包含 6 种括号 /*** param {string} s* return {boolean}*/ var isValid function(s) {const map {"(":")","{":"}","["…

vue3若依框架,在页面中点击新增按钮跳转到新的页面,不是弹框,如何实现

在router文件中的动态路由数组中新增一个路由配置&#xff0c;这个配置的就是新的页面。 注意path不要和菜单配置中的路径一样&#xff0c;会不显示内容。 在菜单配置中要写权限标识就是permissions:[]里的内容 在children里的path要写占位符info/:data 点击新增按钮&#x…

初级数据结构(三)——栈

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;二&#xff09;——链表 | 初级数据结构&#xff08;四&#xff09;——队列 下一篇-> 1、栈的特性 1.1、函数栈帧简述 即使是刚入门几天的小白&#xff0c;对栈这个字…

一文读懂NISQ时代的量子竞赛

/目录/ 一、关于NISQ&#xff0c;业内专家怎么看&#xff1f; 二、NISQ时代的量子硬件资源估算 2.1. NISQ量子比特要求 2.2. NISQ计算时间 2.3. NISQ代码经典模拟 三、主流量子算法“优势”的资源估算 3.1. 用于化学模拟的VQE算法 3.2. 用于组合优化的QAOA算法 3.3. 量…