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

LeetCode Hot100 - 子串篇

前言

        挑战一个月刷完力扣的hot100,记录一下每题的思路~

        这次是子串相关的题目

(1)560. 和为 K 的子数组

        ①暴力枚举,使用一个变量sum记录以l开头r结尾的情况

class Solution {public int subarraySum(int[] nums, int k) {int res=0;// 枚举每种情况for(int l=0;l<nums.length;l++){int sum=0; // l开头for(int r=l;r<nums.length;r++){ // r结尾sum+=nums[r];if(sum==k)res++; // 满足条件}}return res;}
}

        ②前缀和+map,map记录每种前缀和出现的次数。若位置i的前缀和为pre,map中存在pre-k的前缀和,即存在某位置到i的和为k,统计次数即可

class Solution {Map<Integer,Integer> map = new HashMap<>(); // 每种前缀和出现次数public int subarraySum(int[] nums, int k) {int res=0, pre=0;map.put(0,1);for(int i=0;i<nums.length;i++){pre+=nums[i]; // 开头到i的和// map中存在前缀和pre-k,即存在某个位置到i的和为kif(map.containsKey(pre-k))res+=map.get(pre-k);map.put(pre,map.getOrDefault(pre,0)+1); // 更新前缀和pre的次数}return res;}
}

(2)239. 滑动窗口最大值

        ①优先队列,记录值和下标,按降序(越大越优先),每次移除下标越界元素,取最大值

class Solution {// 优先队列,存值和下标,按值降序,即越大优先级越高PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->Integer.compare(b[0],a[0]));List<Integer> res = new ArrayList<>();public int[] maxSlidingWindow(int[] nums, int k) {for(int i=0;i<k;i++)pq.offer(new int[]{nums[i],i});res.add(pq.peek()[0]); // 第一种情况for(int i=k;i<nums.length;i++){pq.offer(new int[]{nums[i],i});while(pq.peek()[1]<=i-k)pq.poll(); // 移除窗口外元素res.add(pq.peek()[0]); // 存最大值}return res.stream().mapToInt(Integer::intValue).toArray(); // 流式转换}
}

        ②单调递减双端队列。若l<r,且nums[l]<nums[r],在后续的窗口中不可能选到l。每次入队为靠后元素,若该元素大于队尾元素,队尾不可能再选到,直接出队。队列保留目前最大值和其后递减较小值。最大值移出滑动窗口时,将其出队

class Solution {List<Integer> res = new ArrayList<>();Deque<Integer> queue = new ArrayDeque<>(); // 单调递减双端队列public int[] maxSlidingWindow(int[] nums, int k) {for(int i=0;i<nums.length;i++){// 移除窗口的元素刚好为队头,出队if(i>=k&&queue.peekFirst()==nums[i-k])queue.pollFirst();// 加入当前元素,满足单调递减while(!queue.isEmpty()&&queue.peekLast()<nums[i])queue.pollLast();queue.addLast(nums[i]);// 遍历到k-1时开始取队头,即目前最大值if(i>=k-1)res.add(queue.peekFirst());}return res.stream().mapToInt(Integer::intValue).toArray();}
}

        ③思路同上一种,单调队列记录下标,用于队头下标越界判断,更好理解

class Solution {List<Integer> res = new ArrayList<>();Deque<Integer> deque = new ArrayDeque<>(); // 单调递减双端队列public int[] maxSlidingWindow(int[] nums, int k) {for(int i=0;i<nums.length;i++){// 加入当前元素,满足单调递减while(!deque.isEmpty()&&nums[deque.peekLast()]<nums[i])deque.pollLast();deque.addLast(i);// 队头出界,移出if(i>=k&&deque.peekFirst()<=i-k)deque.pollFirst();// 遍历到k-1时开始取队头,即目前最大值if(i>=k-1)res.add(nums[deque.peekFirst()]);}return res.stream().mapToInt(Integer::intValue).toArray();}
}

        ④分组+最大前后缀。k个数一组,计算每组最大前后缀。窗口起始值i,若为k的整数倍,即窗口恰好为一组;否则,窗口跨越两个分组,取前一个分组最大后缀和后一个分组最大前缀的最大值

class Solution {List<Integer> res = new ArrayList<>();public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;int[] prefixMax=new int[n], suffixMax=new int[n];for(int i=0,j=n-1;i<n;i++,j--){// 下标为k整数倍,组头if(i%k==0)prefixMax[i]=nums[i]; else prefixMax[i]=Math.max(prefixMax[i-1],nums[i]);// 数组最后一位或下标后一位为k整数倍,组尾if(j==n-1||(j+1)%k==0)suffixMax[j]=nums[j]; else suffixMax[j]=Math.max(suffixMax[j+1],nums[j]);}// i为窗口起始位置// i为k整数倍,窗口恰为一个分组// 否则窗口跨越两个分组,取前一个分组最大后缀和后一个分组最大前缀的最大值for(int i=0;i<=n-k;i++)res.add(Math.max(suffixMax[i],prefixMax[i+k-1]));return res.stream().mapToInt(Integer::intValue).toArray();}
}

(3)76. 最小覆盖子串

        滑动窗口。map和count分别记录t和滑动窗口的字符数,check判断count不小于map,即滑动窗口满足条件。r扩张直到check为true,然后收缩l直到不满足,记录最短滑动窗口

class Solution {Map<Character,Integer> map = new HashMap<>();Map<Character,Integer> count = new HashMap<>();public String minWindow(String s, String t) {if(s.length()<t.length())return ""; // 长度不够int l=0,r=-1,sLen=s.length(),tLen=t.length(); // 滑动窗口int resL=-1,resR=-1; // 结果下标// t中字符计数for(char c:t.toCharArray())map.put(c,map.getOrDefault(c,0)+1);// s滑动窗口while(r<sLen){r++; // 扩张if(r<sLen&&map.containsKey(s.charAt(r)))count.put(s.charAt(r),count.getOrDefault(s.charAt(r),0)+1);while(check()&&l<=r){if(resL==-1||r-l<resR-resL){resL=l;resR=r;}if(map.containsKey(s.charAt(l)))count.put(s.charAt(l),count.getOrDefault(s.charAt(l),0)-1);l++; // 收缩}}return resL==-1?"":s.substring(resL,resR+1);}// count不小于map个数boolean check(){for(Character c:map.keySet()){if(count.getOrDefault(c,0)<map.get(c))return false;}return true;}
}

总结

        ①子串双指针暴力枚举;map记录每种前缀和出现次数,统计pre-k存在次数

        ②和为K的子串优先队列记录值和下标,值大优先,下标限界;单调递减双端队列,位于前面且更小的值不会再被选中;分组+最大前后缀,预处理分组的前后缀,滑动窗口恰为分组,或跨越两个分组

        ③滑动窗口最大值滑动窗口,r扩张找到满足的情况,l收缩尽可能最短

相关文章:

LeetCode Hot100 - 子串篇

前言 挑战一个月刷完力扣的hot100&#xff0c;记录一下每题的思路~ 这次是子串相关的题目 &#xff08;1&#xff09;560. 和为 K 的子数组 ①暴力枚举&#xff0c;使用一个变量sum记录以l开头r结尾的情况 class Solution {public int subarraySum(int[] nums, int k) {int r…...

【Android】Convenient ADB Commands

Install adb install -r <path>Uninstall adb uninstall <pkg>Start adb shell am start -n <pkg>/.SplashActivityStop adb shell am force-stop <pkg>Reset adb shell pm clear <pkg>Reboot adb rebootShutdown adb reboot -p...

elementUI 时间控件控制时间选择

选择时间大于当前月或小于2024年一月禁止选择 <el-form-item label"成交月份:" label-width"105px" ><div class"block"><el-date-pickerv-model"formData.deal_month"type"month":picker-options"pick…...

什么是x86架构,什么是arm架构

什么是 x86 架构&#xff1f; x86 架构是一种经典的指令集架构&#xff08;ISA&#xff09;&#xff0c;最早由英特尔在 1978 年推出&#xff0c;主要用于 PC、服务器等领域。 它是一种复杂指令集计算&#xff08;CISC&#xff09;架构&#xff0c;支持大量的复杂指令和操作&…...

c语言水仙花,超简单讲解

效果 3或者大于3位数 每一位的位数次方相加等于 自身 例如 153 13 53 33 结果为112527 153 1634&#xff1a; 计算过程&#xff1a; 14643444112968125616341^4 6^4 3^4 4^4 1 1296 81 256 16341464344411296812561634 过程 求得单独将所有位数的正数拎出来…...

Flutter 13 网络层框架架构设计,支持dio等框架。

在移动APP开发过程中&#xff0c;进行数据交互时&#xff0c;大多数情况下必须通过网络请求来实现。客户端与服务端常用的数据交互是通过HTTP请求完成。面对繁琐业务网络层&#xff0c;我们该如何通过网络层架构设计来有效解决这些问题&#xff0c;这便是网络层框架架构设计的初…...

Python小白学习教程从入门到入坑------第二十课 闭包修饰器(语法基础)

一、递归函数 1.1 基本信息 递归函数是指一个函数在其定义中直接或间接地调用了自身 递归在解决许多问题&#xff08;如树的遍历、图的搜索、数学中的分治算法等&#xff09;时非常有用 在Python中&#xff0c;递归函数可以通过简单的语法来实现 然而&#xff0c;使用递归…...

Vue+element-ui实现网页右侧快捷导航栏 Vue实现全局右侧快捷菜单功能组件

Vue+element-ui实现网页右侧快捷导航栏 Vue实现全局右侧快捷菜单功能组件 可视区域没超过当前屏幕高度时候只显示三个菜单效果 可视区域超过当前屏幕高度时,显示可回到顶部菜单的,当然这个菜单显示条件可以自定义,根据需求设置 然后将这个整体功能创建为一个全局组件 代…...

如何配置,npm install 是从本地安装依赖

在 Node.js 中&#xff0c;要使npm install从本地安装依赖&#xff0c;可以按照以下步骤进行配置&#xff1a; 一、准备本地依赖包 确保你有本地的依赖包。这个依赖包可以是一个包含package.json文件的文件夹&#xff0c;或者是一个已经打包好的.tgz文件。 二、使用相对路径…...

Python画图3个小案例之“一起看流星雨”、“爱心跳动”、“烟花绚丽”

源码如下&#xff1a; import turtle # 导入turtle库&#xff0c;用于图形绘制 import random # 导入random库&#xff0c;生成随机数 import math # 导入math库&#xff0c;进行数学计算turtle.setup(1.0, 1.0) # 设置窗口大小为屏幕大小 turtle.title("流星雨动画&…...

Knife4j配置 ▎使用 ▎教程 ▎实例

knife4j简介 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试.参数和格式都…...

电子电气架构 --- 车载芯片现状

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…...

Unity 二次元三渲二

三渲二 注意&#xff1a;Unity必须是2022.3LTS及以上和URP项目&#xff01;&#xff01;&#xff01; 下载三渲二插件 【如何将原神的角色导入Unity】全网最细致教程&#xff0c;全程干货。不使用任何收费插件&#xff0c;使用Spring Bone对头发和衣服进行物理模拟。_原神 步…...

echart实现地图数据可视化

文章目录 [TOC](文章目录) 前言一、基本地图展示2.数据可视化 总结 前言 最近工作安排使用echarts来制作图形报表&#xff0c;记录一下我的步骤&#xff0c;需求呈现一个地图&#xff0c;地图显示标签&#xff0c;根据业务指标值给地图不同省市填充不同颜色&#xff0c;鼠标放…...

网关三问:为什么微服务需要网关?什么是微服务网关?网关怎么选型?

文章整体介绍 本文旨在解答关于微服务网关的三个核心问题&#xff1a; 1&#xff09;为什么需要网关&#xff1f;也即在何种场景下应采用微服务网关以优化系统架构&#xff1b; 2&#xff09;什么是微服务网关&#xff1f;主要讲构成微服务网关的关键能力&#xff0c;包括但…...

Mybatis-plus解决兼容oracle批量插入

本博客借鉴网上很多大佬的答案&#xff0c;东拼西凑&#xff0c;最终在项目中完成批量插入&#xff0c;仅供参考~~~ 1. 自定义SQL注入器 新建一个名为EasySqlInjector的类&#xff0c;继承DefaultSqlInjector。 public class EasySqlInjector extends DefaultSqlInjector {O…...

Kaggle竞赛——灾难推文分类(Disaster Tweets)

目录 1. 准备工作2. 资源导入3. 数据处理4. 绘制词云图5. 数据可视化5.1 词数和字符数可视化5.2 元特征可视化5.3 类别可视化 6. 词元分析6.1 一元语法统计6.2 多元语法统计 7. 命名实体识别8. 推文主题提取9. 构建模型9.1 数据划分与封装9.2 模型训练与验证 10. 模型评估11. 测…...

SC2601音频编解码器可pin to pin兼容ES8311

SC2601 是一款低功耗单声道音频编解码器&#xff0c;具有全差分输出&#xff0c;支持在全差分配置下可编程模拟输入。可pin to pin兼容ES8311。 录音路径包含一个全差分输入&#xff0c;低噪声可编程增益放大器和自动增益控制&#xff08;ALC&#xff09;。在录音过程中,通过内…...

通用AT指令

1、查询SIM卡状态 ATCPIN?2、查询信号强度 ATCSQ //99,99 表示无信号3、查询IMEI ATCGSN4、查询4G/5G模式 ATCOPS? //7表示在4G模式&#xff0c;13表示在5G模式5、设置接入点 ATCGDCONT1,"IP","uninet" //联通 ATCGDCONT1,"IP","…...

二进制狼群算法

本文所涉及所有资源均在 传知代码平台 可获取。 目录 一、背景及意义介绍 背景 意义...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...