Top100 子串

1.560. 和为 K 的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 

子数组是数组中元素的连续非空序列。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 2 * 10^4
  • -1000 <= nums[i] <= 1000
  • -10^7 <= k <= 10^7

思路:

数据规模也蛮大;思考是不是用滑动窗口,因为是子串,不允许排序,所以用滑动窗口,不断往后移,暴力枚举遍历。

代码:

暴力没成功,当个反面例子,我先贴一会

class Solution(object):def subarraySum(self, nums, k):i,k=0,0count=0for i in range(len(nums)):for j in range(i,len(nums)):if sum(nums[i:j])==k : print(i,j)print(sum(nums[i:j]))count+=1return count

换个思路:

使用前缀和的方法可以解决这个问题,因为我们需要找到和为k的连续子数组的个数。通过计算前缀和,我们可以将问题转化为求解两个前缀和之差等于k的情况。

假设数组的前缀和数组为prefixSum,其中prefixSum[i]表示从数组起始位置到第i个位置的元素之和。那么对于任意的两个下标i和j(i < j),如果prefixSum[j] - prefixSum[i] = k,即从第i个位置到第j个位置的元素之和等于k,那么说明从第i+1个位置到第j个位置的连续子数组的和为k。

通过遍历数组,计算每个位置的前缀和,并使用一个哈希表来存储每个前缀和出现的次数。在遍历的过程中,我们检查是否存在prefixSum[j] - k的前缀和,如果存在,说明从某个位置到当前位置的连续子数组的和为k,我们将对应的次数累加到结果中。

这样,通过遍历一次数组,我们可以统计出和为k的连续子数组的个数,并且时间复杂度为O(n),其中n为数组的长度。

每次的前缀和放入map哈希表中,哈希表的索引是pre,如果未出现过,则创建一个键值对。

class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int, int> mp;mp[0] = 1;int count = 0, pre = 0;for (auto& x:nums) {pre += x;if (mp.find(pre - k) != mp.end()) {count += mp[pre - k];}mp[pre]++;}return count;}
};

2.239. 滑动窗口最大值

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

返回 滑动窗口中的最大值 

示例 1:

输入: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       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  3  -1  -3  5 [3  6  7]      7

示例 2:

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

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= nums.length

思路:

1)先是暴力解法,就可以按照遍历的方式,从头到尾,以k为长度,然后寻找最大值放入答案的列表中。

2)稍微优化一点点,首先将前k个元素排序,然后进行遍历。遍历过程中需要判断:
是否大于最大值,如果是,则作为队首元素,队尾出队;如果小于最小值,则直接舍弃;如果处于中间,则队尾元素出队,该元素入队;结束后重新排序!(写到这自己都觉得蠢了,这叫优化??)

3)使用双项队列。这里为了效率和快捷使用了 deque 容器,也可以使用 list 容器。

声明了一个变量 deque<int>window,用于存储下标。这个变量有以下 特点:

①变量的最前端(也就是 window.front())是此次遍历的最大值的下标
②当我们遇到新的数时,将新的数和双项队列的末尾(也就是window.back())比较,如果末尾比新数小,则把末尾扔掉,直到该队列的末尾比新数大或者队列为空的时候才停止,做法有点像使用栈进行括号匹配。
③双项队列中的所有值都要在窗口范围内
特点一只是方便我们获取每次窗口滑动一格之后的最大值,我们可以直接通过 window.front() 获得。通过特点二,可以保证队列里的元素是从头到尾降序的,由于队列里只有窗口内的数,所以他们其实就是窗口内第一大,第二大,第三大... 的数。特点三就是根据题意设置的。但我们实际上只用比较现在的下标和 window.front() 就可以了,为什么呢?
因为只要窗口内第一大元素也就是这个 window.front() 在窗口内,那我们可以不用管第二大第三大元素在不在区间内了。因为答案一定是这个第一大元素。如果 window.front() 不在窗口内,则将其弹出,第二个大元素变成第一大元素,第三大元素变成第二大元素以此类推。

代码编写的过程还要时刻检查队列是否为空防止抛出异常,根据上面这些信息我们就可以编写此题的代码了。

代码:

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {if(k==0)return {};vector<int>res;deque<size_t>window;/*Init K integers in the list*/for (size_t i = 0; i < k; i++) {while (!window.empty()  && nums[i] > nums[window.back()]) {window.pop_back();}window.push_back(i);}res.push_back(nums[window.front()]);/*End of initialization*/for (size_t i = k; i < nums.size(); i++) {if (!window.empty() && window.front() <= i - k) {window.pop_front();}while (!window.empty() && nums[i] > nums[window.back()]) {window.pop_back();}window.push_back(i);res.push_back(nums[window.front()]);}return res;}
};

3.76. 最小覆盖子串

 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

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

示例 2:

输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。

示例 3:

输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 10^5
  • s 和 t 由英文字母组成

思路:

这个不会!直奔题解!

双指针,我们移动右指针同时统计可以匹配目标字符串的字符个数,当一个右指针可以匹配所有的目标字串时,我们更新左端点找到一个最短的子串。

代码:

class Solution {
public:string minWindow(string s, string t) {int n = s.size(), m = t.size();vector<int> res(2, INT_MAX);unordered_map<char, int> h;unordered_map<char, int> hs;for(auto e : t) hs[e]++;int cnt = 0;for(int i = 0, j = 0; i < n; i++){h[s[i]]++;if(hs.find(s[i]) != hs.end()){if(h[s[i]] == hs[s[i]]) cnt++; // 统计当前s中可以匹配t的字符个数}while(cnt == hs.size()) // 可以匹配所有字符时,说明我们找到了一个合法子串{// 尝试更新左端点找到一个最短的子串h[s[j]]--;if(hs.find(s[j]) != hs.end()){if(h[s[j]] < hs[s[j]]) // 左端点的字符更新后如果无法满足和t匹配更新答案和种类数{cnt--;if(i - j + 1 < res[0]){res[0] = i - j + 1;res[1] = j;}}}j++;}}if(res[0] == INT_MAX) return ""; // 无法匹配当前的t字符串return s.substr(res[1], res[0]);}
};

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

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

相关文章

VUE引入DataV报错记录

DataV官网&#xff08;不支持Vue3&#xff09;&#xff1a;Welcome | DataV 一、按照官网引入后报错 【1】 Failed to resolve entry for package "dataview/datav-vue3". The package may have incorrect main/module/exports specified in its package.json. 将…

服务器托管与虚拟主机租用有哪些区别?

服务器托管又称为主机托管&#xff0c;是用户自身拥有一台服务器放置在数据中心的机房里&#xff0c;主要是由客户自己进行维护&#xff0c;用户自身就可以进行操作系统&#xff0c;企业将服务器放置在专用的托管服务器机房中&#xff0c;可以享受到稳定舒适的机房环境&#xf…

ARC143D Bridges

题目 把 i i i 和 i n in in 看作一个点&#xff0c;对所有 a i a_i ai​ 和 b i b_i bi​ 连边&#xff0c;得到的图称为 G G G&#xff0c;则 G G G 的割边 ( a i , b i ) (a_i,b_i) (ai​,bi​) 在原图中 ( a i , b i n ) (a_i,b_in) (ai​,bi​n) 或 ( a i n ,…

【Matlab】音频信号分析及FIR滤波处理——凯泽(Kaiser)窗

一、前言 1.1 课题内容: 利用麦克风采集语音信号(人的声音、或乐器声乐),人为加上环境噪声(窄带)分析上述声音信号的频谱,比较两种情况下的差异根据信号的频谱分布,选取合适的滤波器指标(频率指标、衰减指标),设计对应的 FIR 滤波器实现数字滤波,将滤波前、后的声音…

贪吃蛇/链表实现(C/C++)

本篇使用C语言实现贪吃蛇小游戏&#xff0c;我们将其分为了三个大部分&#xff0c;第一个部分游戏开始GameStart&#xff0c;游戏运行GameRun&#xff0c;以及游戏结束GameRun。对于整体游戏主要思想是基于链表实现&#xff0c;但若仅仅只有C语言的知识还不够&#xff0c;我们还…

Compose开发No virtual method at(Ljava/lang/Object;I)错误【已解决】

此问题主要是在用CircularProgressIndicator时报错的&#xff0c;其他没遇到。 在升级不同版本时出现了不少问题&#xff0c;现在记录一下 1、mutableIntStateOf()函数的出现 要将此条版本更新到2.6.2及以上 implementation("androidx.lifecycle:lifecycle-runtime-ktx:…

学习笔记推荐:极客时间《Java常见错误100例》

最近&#xff0c;我有幸接触了一套非常精彩的学习笔记&#xff0c;《Java常见错误100例》。&#xff08;手册链接在文末&#xff01;&#xff01;&#xff01;&#xff09; 这套学习笔记出自极客时间&#xff0c;对于想要在 Java 开发领域深耕细作的朋友们来说&#xff0c;它无…

SpringBoot内置工具类

Collections java.util包下的Collections类&#xff0c;该类主要用于操作集合或者返回集合 一、排序 List<Integer> list new ArrayList<>();list.add(2);list.add(1);list.add(3);Collections.sort(list);//升序System.out.println(list);Collections.reverse(…

hot100 -字母异位词分组

题目介绍 给定一个字符串数组&#xff0c;要求将其中的字母异位词组合在一起&#xff0c;并可以按任意顺序返回结果列表。字母异位词是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[…

WPF的ViewBox控件

在WPF中&#xff0c;ViewBox是一个用于缩放和调整其子元素大小的容器控件。它可以根据可用空间自动调整子元素的大小&#xff0c;以使其适应ViewBox的边界。这使得在不同尺寸的窗口或布局中保持元素的比例和缩放变得更加容易。 ViewBox具有以下重要属性&#xff1a; Stretch&…

基于Python flask MySQL 猫眼电影可视化系统设计与实现

1 绪论 1.1 设计背景及目的 猫眼电影作为国内知名的电影信息网站&#xff0c;拥有海量的电影信息、票房数据和用户评价数据。这些数据对于电影市场的研究和分析具有重要意义。然而&#xff0c;由于数据的复杂性和数据来源的多样性&#xff0c;如何有效地采集、存储和展示这些数…

【Linux 内核源码分析】多核调度分析

多核调度 SMP&#xff08;Symmetric Multiprocessing&#xff0c;对称多处理&#xff09;是一种常见的多核处理器架构。它将多个处理器集成到一个计算机系统中&#xff0c;并通过共享系统总线和内存子系统来实现处理器之间的通信。 首先&#xff0c;SMP架构将一组处理器集中在…

程序员的基本素养之——R语言起源、特点以及应用

R语言是一种功能强大的数据分析、统计建模、可视化、 免费、开源且跨平台的编程语言 作为用于数据统计的必备技能语言&#xff0c;博主目前正在对R语言进行基本的学习&#xff0c;这也是生物信息学领域进行统计分析的必备语言之一。下面跟我来一起看看吧&#xff01; R语言是一…

鸿蒙自定义Http网络访问组件

前言 DevEco Studio版本:4.0.0.600 使用效果 如何使用 参考文档:OpenHarmony http数据请求 1、module创建 File-->New-->Module,选择Static Library 2、相关类创建 HttpCore:Http的核心类,用于http的请求 RequestMethod:http请求的类型,包含:GET、POST等 …

基本数据类型细节【java】

整形细节 1.java个整数类型有固定的范围和字段长度&#xff0c;不受具体OS【操作系统】的影响&#xff0c;以保证java程序的移植性 2.java的整型常量默认为int型&#xff0c;声明long型常量须在后面加l或者L int n1 1;//4个字节 //int n2 1L;//不对 long n3 1L; //对 3.J…

你好,C++(9)坐216路公交车去买3.5元一斤的西红柿——C++中如何表达各种数值数据 3.3 数值数据类型

3.3 数值数据类型 从每天早上睁开眼睛的那一刻开始&#xff0c;我们几乎每时每刻都在与数字打交道&#xff1a;从闹钟上的6点30分&#xff0c;到上班坐的216路公共汽车&#xff1b;从 新闻中说的房价跌到了100元每平米到回家买菜时的西红柿3.5元一斤。我们生活在一个充满数字的…

个性化联邦学习所面临的挑战:

个性化联邦学习所面临的挑战&#xff1a; 1、Federated Learning with Personalization Layers Li等人(2019)最近发表的综述文章阐述了联邦学习系统面临的许多独特挑战。其中一个挑战是&#xff0c;不同客户端的有效数据分布可能在参与的设备之间(可能有数百万台)差异很大。这…

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合

目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步&#xff1a;采用事件风暴。 第 2 步&#xff1a;选出聚合根。 第 3 步&#xff1a;找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步&#xff1a;画出对象的引用和依赖模型…

强缓存与协商缓存、缓存失效的问题、缓存nginx配置、缓存存在哪里

前端缓存&#xff0c;这是一个老生常谈的话题&#xff0c;也常被作为前端面试的一个知识点。今天我们来总结一下。 分类&#xff1a;前端缓存分为强缓存和协商缓存两种。 强缓存 强缓存主要使用 Expires、Cache-Control 两个头字段&#xff0c;两者同时存在 Cache-Control 优…

P2246 SAC#1 - Hello World(升级版)

网址如下&#xff1a; P2246 SAC#1 - Hello World&#xff08;升级版&#xff09; - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 刚开始是用递归做的&#xff0c;虽然用了哈希表优化&#xff0c;但是超时&#xff0c;只得了50 后面想到了一个新的算法&#xff0c;时间复杂度…