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

LeetCode HOT100(四)字串

和为 K 的子数组(mid)

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。

输入:nums = [1,1,1], k = 2
输出:2


解法1:前缀和+Map
这是一道经典的前缀和运用题。
统计以每一个 nums[i] 为结尾,和为 k 的子数组数量即是答案。
我们可以预处理前缀和数组 prefix,对于求解以某一个 nums[i] 为结尾的,和为 k 的子数组数量,本质上是求解在 [0,i] 中,prefix 数组中有多少个值为 prefix[i]−k 的数,这可以在遍历过程中使用「哈希表」进行同步记录。
是以当前节点为结尾的计算,不是以当前节点为起始的计算!!!

public int subarraySum(int[] nums, int k) {int len = nums.length;int[] prefix = new int[len];prefix[0] = nums[0];for (int i=1; i<len; i++){prefix[i] = prefix[i-1]+nums[i];}Map<Integer,Integer> map = new HashMap<>();//当子串的起始节点为0,即取前缀和的整段而不做截断//需要插入一个长度为0的子串map.put(0,1);int res = 0;for(int i=0; i<len; i++){res += map.getOrDefault(prefix[i]-k,0);map.put(prefix[i],map.getOrDefault(prefix[i],0)+1);}return res;
}

滑动窗口最大值(hard)

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值


[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7


解法1:滑动窗口,最优
假设我们当前处理到某个长度为 k 的窗口,此时窗口往后滑动一格,会导致后一个数(新窗口的右端点)添加进来,同时会导致前一个数(旧窗口的左端点)移出窗口。
随着窗口的不断平移,该过程会一直发生。若同一时刻存在两个数 nums[j] 和 nums[i](j<i)所在一个窗口内,下标更大的数会被更晚移出窗口,此时如果有 nums[j]<=nums[i] 的话,可以完全确定 nums[j] 将不会成为后续任何一个窗口的最大值,此时可以将必然不会是答案的 nums[j] 从候选中进行移除
不难发现,当我们将所有必然不可能作为答案的元素(即所有满足的小于等于 nums[i] )移除后,候选集合满足「单调递减」特性,即集合首位元素为当前窗口中的最大值(为了满足窗口长度为 k 的要求,在从集合头部取答案时需要先将下标小于的等于的 i−k 的元素移除)。
为方便从尾部添加元素,从头部获取答案,我们可使用「双端队列」存储所有候选元素。
用一个容器,充当窗口,保持它存储的元素是单调非递增,这样它的第一个元素就是容器中的最大值,最后一个就是最小值,根据前面的分析,向右滑动过程中,如果遇到了更大的元素,就可以把在容器中小于它的元素都移除掉,因为后加入的更大的元素才可能成为容器中的最大值。因为第一个元素是最大值,我们需要能够获取它,所以,这是一个先入先出的容器,这里用队列就可以了。它的思路与单调栈一样,但只不过用队列来当容器,这便是“单调队列”了。

public int[] maxSlidingWindow(int[] nums, int k) {Deque<Integer> stack = new ArrayDeque<>();int[] res = new int[nums.length-k+1];for(int i=0; i<nums.length; i++){// 队列中的下标是小于新加入的i,那么如果[i]>= 队尾// 说明队尾肯定不会是窗口里的一个最大值了// 从队尾开始,把小于[i]的都移除掉。// 这样就能保证队列的值是一个单调非递减队列了while(!stack.isEmpty() && nums[stack.peekLast()]<nums[i]){stack.pollLast();}stack.addLast(i);if(i>=k-1){// 现在的队首就是窗口中的最大值res[i-k+1] = nums[stack.peekFirst()];// 再把左滑出窗口的最大值从队列中移除,因为它已被滑出窗口了if(stack.peekFirst()+k-1 == i) stack.pollFirst();}}return res;
}

解法2:优先队列
image.png

public int[] maxSlidingWindow(int[] nums, int k) {// 使用优先队列(大顶堆)来存储窗口中的索引,以便快速找到最大值PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> nums[b] - nums[a]);// 初始化结果数组,长度为 nums 数组长度减去窗口大小 k 再加 1int[] res = new int[nums.length - k + 1];for (int i = 0; i < nums.length; i++) {// 将当前索引 i 加入优先队列pq.add(i);// 当索引 i 大于 k-1 时,说明窗口已经滑动了至少 k 次,可以开始记录最大值if (i >= k - 1) {// 记录窗口内的最大值,即优先队列中索引对应的值res[i - k + 1] = nums[pq.peek()];// 清除出窗口的元素,即索引小于 i-k+1 的元素while (!pq.isEmpty() && pq.peek() <= i - k + 1) {pq.poll();}}}// 返回结果数组,包含了每个窗口的最大值return res;
}

最小覆盖字串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。


解法1:滑动窗口

public String minWindow(String s, String t) {// 初始化一个足够大的数组来计数字符,假设字符集大小为70(A-Z的大小写)int[] cnt = new int[70];// 标记是否找到有效子串boolean flag = false;// 遍历字符串 t,对每个字符进行计数,并将对应的数组元素减1for (int i = 0; i < t.length(); i++) {char c = t.charAt(i);cnt[c - 'A']--; // 将字符转换为0-65的整数,便于在数组中索引}// 初始化结果字符串为 s,假设没有找到更小的子串String res = s;// 初始化左右指针int l = 0, r = 0;// 滑动窗口的右边界while (r < s.length()) {// 将 s 的当前字符计数加1cnt[s.charAt(r) - 'A']++;// 当前窗口包含 t 的所有字符时,尝试收缩左边界while (l <= r && check(cnt)) {// 标记已找到有效子串flag = true;// 更新最小窗口String tmp = s.substring(l, r + 1);res = tmp.length() < res.length() ? tmp : res;// 移动左边界,将 l 所指的字符从计数器中减去cnt[s.charAt(l) - 'A']--;l++;}// 扩展右边界,继续寻找可能的最小子串r++;}// 如果找到了有效子串,返回 res,否则返回空字符串return flag ? res : "";
}// 检查数组中的所有计数是否都大于等于0,即 s 的当前窗口是否包含 t 的所有字符
public boolean check(int[] arr) {for (int i = 0; i < arr.length; i++) {if (arr[i] < 0)return false; // 如果有字符计数小于0,则当前窗口不包含 t 的所有字符}return true; // 所有字符计数都非负,说明当前窗口包含 t 的所有字符
}

定义两个长度为 60(足够存下所有字母种类)的数组 c1 和 c2,用于存储字符频率。其中 c1 用于记录字符串 t 中字符的频率,c2 用于记录当前滑动窗口内字符的频率。
设定好字母与频率数组下标的映射关系:小写字母 a-z 对应下标 0-25,大写字母 A-Z 对应下标 26-51。
使用变量 tot 来记录还需要匹配的字符种类数,当 tot = 0 代表当前滑动窗口对应的子串能够实现对 t 的覆盖,即任意字符满足 c2[i]≥c1[i]。
使用双指针 j 和 i 表示滑动窗口的左右边界。从前往后遍历字符串 s,在每个位置上更新字符频率数组 c2。若 c2 中字符的频率达到了 c1 中的字符频率,则将 tot 减 1,表示一个字符已经匹配完成。
每当右边界往后移动一步之后,滑动窗口会增加一个字符。此时我们检查左边界能否右移,同时不会使得 tot 变大。即每次右边界右移后,我们检查左边界 c2[j]>c1[j] 是否满足:

  • 若满足:说明当前左边界指向字符并非必须,当前子串 s[j…i] 必然不是最短子串。我们让左边界 j 进行右移,并重复进行左边界 c2[j]>c1[j] 的检查,直到窗口不能再收缩
  • 若不满足:说明当前窗口没有任何一个后缀字符串能够实现对 t 的覆盖,我们并不能对窗口实现收缩

每次对窗口移动完成后,我们检查当前 tot 是否为 0(对字符串 t 的覆盖是否完成),若为 0 则尝试用当前窗口对应的字符串 s[j…i] 更新 ans。

class Solution {public String minWindow(String s, String t) {int n = s.length(), tot = 0;int[] c1 = new int[60], c2 = new int[60];for (char x : t.toCharArray()) {if (++c1[getIdx(x)] == 1) tot++;}String ans = "";for (int i = 0, j = 0; i < n; i++) {int idx1 = getIdx(s.charAt(i));if (++c2[idx1] == c1[idx1]) tot--;while (j < i) {int idx2 = getIdx(s.charAt(j));if (c2[idx2] > c1[idx2] && --c2[idx2] >= 0) j++;else break;}if (tot == 0 && (ans.length() == 0 || ans.length() > i - j + 1)) ans = s.substring(j, i + 1);}return ans;}int getIdx(char x) {return x >= 'A' && x <= 'Z' ? x - 'A' + 26 : x - 'a';}
}

相关文章:

LeetCode HOT100(四)字串

和为 K 的子数组&#xff08;mid&#xff09; 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 解法1&#xff1a;前缀和Map 这…...

uniapp引入 uview( HBuilder 和 npm 两种安装方式) #按需引入

方式一、HBuilder 安装 uview 1.1. HBuider安装-链接-》》 1.2. 在uni.scss 中引入 import "uni_modules/uview-ui/theme.scss";1.3. main.js 引入&#xff08;import Vue from ‘vue’ 下面&#xff09; import uView from "uni_modules/uview-ui"; V…...

使用uni-app和Golang开发影音类小程序

在数字化时代&#xff0c;影音内容已成为人们日常生活中不可或缺的一部分。个人开发者如何快速构建一个功能丰富、性能优越的影音类小程序&#xff1f;本文将介绍如何使用uni-app前端框架和Golang后端语言来实现这一目标。 项目概述 本项目旨在开发一个个人影音类小程序&#…...

基于Go1.19的站点模板爬虫详细介绍

构建一个基于Go1.19的站点模板爬虫是一项有趣且具有挑战性的任务。这个爬虫将能够从网站上提取数据&#xff0c;并按照指定的模板进行格式化。以下是详细的介绍和实现步骤。 1. 准备工作 工具和库&#xff1a; Go 1.19colly&#xff1a;一个强大的Go爬虫库goquery&#xff1…...

永恒之蓝:一场网络风暴的启示

引言 在网络安全的漫长历史中&#xff0c;“永恒之蓝”&#xff08;EternalBlue&#xff09;是一个不可忽视的里程碑事件。它不仅揭示了网络世界的脆弱性&#xff0c;还促使全球范围内对网络安全的重视达到了前所未有的高度。本文将深入探讨“永恒之蓝”漏洞的起源、影响及其对…...

AI绘画:艺术与科技的交融,创新浪潮与无限可能

在科技日新月异的当下&#xff0c;AI 绘画作为人工智能领域的一颗璀璨新星&#xff0c;正以惊人的速度在国内崭露头角&#xff0c;引发了艺术与技术交融的全新变革。随着人工智能技术的飞速发展&#xff0c;AI绘画已成为艺术与科技交融的新宠。2024年&#xff0c;AI绘画行业在国…...

医疗健康信息的安全挑战与隐私保护最佳实践

医疗健康信息的安全挑战 医疗健康信息的安全挑战主要包括数据规模庞大、管理困难、数据类型多样导致的安全风险高、以及法律法规与伦理约束带来的挑战。随着医疗信息化的发展&#xff0c;医疗健康数据呈现出爆炸式的增长&#xff0c;医院信息系统、电子病历、健康管理等产生了海…...

《C++并发编程实战》笔记(一、二)

一、简介 抽象损失&#xff1a;对于实现某个功能时&#xff0c;可以使用高级工具&#xff0c;也可以直接使用底层工具。这两种方式运行的开销差异称为抽象损失。 二、线程管控 2.1 线程的基本控制 1. 创建线程 线程相关的管理函数和类在头文件&#xff1a; #include <…...

【日常bug记录】el-checkbox 绑定对象数组

版本说明 "vue": "2.6.10", "element-ui": "2.13.2", 这个写法很怪异哦&#xff0c;但确实管用。el-checkbox 绑定的 label 是双向绑定的值&#xff0c;也就是选中之后传到表单数据里面的值&#xff0c;一般设置为 id&#xff0c;然后…...

单元测试Mockito笔记

文章目录 单元测试Mockito1. 入门1.1 什么是Mockito1.2 优势1.3 原理 2. 使用2.0 环境准备2.1 Mock1) Mock对象创建2) 配置Mock对象的行为(打桩)3) 验证方法调用4) 参数匹配5) 静态方法 2.2 常用注解1) Mock2) BeforeEach 与 BeforeAfter3) InjectMocks4) Spy5) Captor6) RunWi…...

基于SpringBoot+VueJS+微信小程序技术的图书森林共享小程序设计与实现:7000字论文+源代码参考

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…...

GitHub连接超时问题 Recv failure: Connection was reset

用手机热点WIF拉取git项目的时候&#xff0c;遇到Recv failure: Connection was reset问题。 解决办法 一、手动开启本地代理 二、在终端&#xff08;cmd&#xff09;输入命令 git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy https:…...

浅谈PostCSS

1. 背景 css的预处理器语言&#xff08;比如 sass&#xff0c; less&#xff0c; stylus&#xff09;的扩展性不好&#xff0c;你可以使用它们已有的功能&#xff0c;但如果想做扩展就没那么容易。 sass是很常用的css预处理器语言&#xff0c;在webpack中要使用它&#xff0c;…...

GCN、GIN

# 使用TuDataset 中的PROTEINS数据集。 # 里边有1113个蛋白质图&#xff0c;区分是否为酶&#xff0c;即二分类问题。# 导包 from torch_geometric.datasets import TUDataset from torch_geometric.data import DataLoader import torch import torch.nn as nn import torch.…...

Web控件进阶交互

Web控件进阶交互 测试时常需要模拟键盘或鼠标操作&#xff0c;可以用Python的ActionChains来模拟。ActionChains是Selenium提供的一个子类&#xff0c;用于生成和执行复杂的用户交互操作&#xff0c;允许将一系列操作链接在一起&#xff0c;然后一次性执行。 from selenium im…...

基于SpringBoot的校园疫情防控系统

你好&#xff0c;我是专注于计算机科学与技术的研究者。如果你对我的工作感兴趣或有任何问题&#xff0c;欢迎随时联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架&#xff0c;B/S架构 工具&#xff1a;Eclipse&#xff0c;Mav…...

elasticsearch 查询超10000的解决方案

前言 默认情况下&#xff0c;Elasticsearch集群中每个分片的搜索结果数量限制为10000。这是为了避免潜在的性能问题。 但是我们 在实际工作过程中时常会遇到 需要深度分页&#xff0c;以及查询批量数据更新的情况 问题&#xff1a;当请求form size >10000 时&#xff0c…...

SpringCloud集成kafka集群

目录 1.引入kafka依赖 2.在yml文件配置配置kafka连接 3.注入KafkaTemplate模版 4.创建kafka消息监听和消费端 5.搭建kafka集群 5.1 下载 kafka Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/downloads.html 5.2 在config目录下做…...

Macos 远程登录 Ubuntu22.04 桌面

这里使用的桌面程序为 xfce, 而 gnome 桌面则测试失败。 1,安装 在ubuntu上&#xff0c;安装 vnc server与桌面程序xfce sudo apt install xfce4 xfce4-goodies tightvncserver 2&#xff0c;第一次启动和配置 $ tightvncserver :1 设置密码。 然后修改配置&#xff1a…...

第十届MathorCup高校数学建模挑战赛-A题:无车承运人平台线路定价问题

目录 摘 要 1 问题重述 1.1 研究背景 1.2 研究问题 2 符号说明与模型假设 2.1 符号说明 2.2 模型假设 3 问题一:模型建立与求解 3.1 问题分析与思路 3.2 模型建立 3.2.1 多因素回归模型 3.3 模型求解 3.3.1 数据预处理 3.3.2 重要度计算 4 问题二:模型建立与求…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...