目录

15.力扣 904.水果成篮

15.1 题目解析:

15.2 算法思路:

15.2.1 暴力解法:

15.2.1 滑动窗口

15.3代码演示:

15.4 总结反思:

16 力扣 438.找出字符串中所有字母的异位词

16.1 题目解析:

16.2算法思路:

16.3 代码实现:

​编辑

16.4 总结反思:

17 力扣 30.串联所有单词的子串

17.1 题目解析:

17.2 算法思路:

17.3 代码演示:

​编辑

17.4 总结反思:

18. 力扣 76。最小覆盖子串

18.1 题目解析:

18.2 算法思路:

18.2.1 暴力枚举+哈希表

​编辑18.2.2 优化解法:

18.3 代码演示:

 18.4 总结反思:

19 力扣 704.二分查找

19.1 题目解析:

 19.2 算法思路:

19.3 代码演示:

​编辑

19.4 总结反思:

 

 


15.力扣 904.水果成篮

15.1 题目解析:

要是单单的看这道题目,确实挺难理解的。不过大家仔细的阅读一下,基本可以理解意思,我把题目给翻译了一下:大体的意思可以翻译为找出一个最长的子数组的长度,子数组中不超过两种类型的水果。 最后返回收集到的最大的水果的数目。

15.2 算法思路:

15.2.1 暴力解法:

解法一就是暴力解法,就是找出子数组,找出其中最长的即可,其中要用到哈希表来存储水果出现的种类。(若表中水果超过了2种,则直接不用往里面放了)。

15.2.1 滑动窗口

最主要的还是第二种解法。不过在直到用到滑动窗口做之前,还需要直到为什么要用到滑动窗口?

那么大家看着这个图,我来给大家分析一下。图中left与right之间是kinds=2,但是如果说left往右挪动一个数字,挪到了新的left的位置,那么请问,kinds的大小会怎么变呢?

1.kinds不变,因为若left与right中间恰好有一种水果有两个,这不正好抵消了吗?那么此时right也不变。

2.kinds变小,此时说明,恰好把那种水果给挪走了。那么此时right右移(增加水果的种类)。

所以说,right从图中的位置开始移动left也一直向右边移动。所以,他们俩是同向的。既然是同向的,那么也就是会用到滑动窗口。并且这个题也涉及到了子数组。

 所以:

1.left,right都是从0开始的。

2.进窗口:这个就是hash[fruits[right]]++.

3.那么判断出窗口的标准就是hash的大小大于2.出窗口,出了窗口之后,hash[fruits[left]]--。减完后,还得加一步判断,如果说你的这个hash[fruits[left]]==0,那么这种水果的数量为0,则要把这种水果从哈希表中给踢出去(种类减一)。之后left才加加。(顺序别搞错了)。因为你left先加加的话,会导致这个位置的水果数量还没判断呢。

15.3代码演示:

1.带容器:若用hash表的话,你得定义两个int,即hash<int,int>,第一个int表示哪种水果,第二个int表示这种水果有几个。并且踢出水果要用hash.erase();

​
//使用哈希表(容器)
int totalFruit(vector<int>& fruits) {unordered_map<int, int> hash; //统计窗⼝内出现了多少种⽔果int n = fruits.size();int ret = 0;int left = 0;int right = 0;int kind = 0;for (; right < n; right++){if (hash[fruits[right]] == 0) kind++;//若这种水果的数量为0,则要加入这种水果hash[fruits[right]]++;//增加这种水果的数量while (hash.size() > 2)//出窗口{hash[fruits[left]]--;if (hash[fruits[left]] == 0)hash.erase(fruits[left]);//将这种水果删除left++;}ret = max(ret, right - left + 1);}return ret;
}
int main()
{vector<int> fruits = { 3,3,3,1,2,1,1,2,3,3,4 };cout << totalFruit(fruits) << endl;return 0;
}​

但是呢,带容器的嘛,肯定时间复杂度不够好。所以下面还有一个利用数组来模拟哈希表的写法:

2.用数组代替哈希,得判断一下,若数组中这种水果数量为0,则数组中还没有这种水果,就要++kinds,踢出元素的时候,也是这种水果的数量减到0的时候,才踢出去。

//使用数组模拟哈希表
int totalFruit(vector<int>& fruits) {int hash[100000] = { 0 };//定义哈希数组存放水果int n = fruits.size();int ret = 0;int left = 0;int right = 0;int kind = 0;for (; right < n; right++){if (hash[fruits[right]] == 0) kind++;//若这种水果的数量为0,则要加入这种水果hash[fruits[right]]++;//增加这种水果的数量while (kind > 2)//出窗口{hash[fruits[left]]--;if (hash[fruits[left]] == 0) kind--;//将这种水果删除left++;}ret = max(ret, right - left + 1);}return ret;
}
int main()
{vector<int> fruits = { 3,3,3,1,2,1,1,2,3,3,4 };cout << totalFruit(fruits) << endl;return 0;
}

15.4 总结反思:

总结下来还是滑动窗口的那些做题方法。

16 力扣 438.找出字符串中所有字母的异位词

16.1 题目解析:

大家仔细阅读题目,就可知异位词是什么。例如:abc,那么abc,acb,bac,bca,cab,cba。均为abc的异位词。

16.2算法思路:

这个的算法思路比较复杂,细节也比较多。

 

 

以上就是本题算法的所有细节与思路了,还是挺多的。关键是不好想。

16.3 代码实现:

//找出字符串中所有字母的异位词
vector<int> findAnagrams(string s, string p) {vector<int> ret;int hash1[26] = { 0 };//这个数组存储p中的字符的个数for (auto& e : p) hash1[e - 'a']++;int hash2[26] = { 0 };//这个数组存储s中的字符个数for (int left = 0, right = 0, count = 0; right < s.size(); right++){char in = s[right];//定义一个进来的变量hash2[in - 'a']++;if (hash2[in - 'a'] <= hash1[in - 'a'])  count++;//count的作用是起到一个统计有效字符的作用if (right - left + 1 > p.size())//此时出窗口的判断条件{char out = s[left];if (hash2[out - 'a'] <= hash1[out - 'a'])  count--;hash2[out - 'a']--;//这个是在判断count后才减的,因为你要是先减完了,那怎么能判断这个位置的字符的个数呢?left++;}if (count == p.size()) ret.push_back(left);}return ret;
}
int main()
{vector<int> outcome;string s("cbaebabacd");string p("abc");outcome = findAnagrams(s, p);for (auto& e : outcome){cout << e << "";}cout << endl;return 0;
}

16.4 总结反思:

本题还是挺有挑战性的。即使你的思路想出来了,但是如果说你的代码能力不够强,也还是写不出这样的代码的。

17 力扣 30.串联所有单词的子串

17.1 题目解析:

大家一看到这是个困难题目,好家伙一下子,全蔫了。没事,不要紧。这道题,你仔细的阅读一下,是不是跟上一题寻找异位词差不多,只不过这里的字符变成了字符串。所以本题的解答思路就是,将这些字符串看成字符进行解答。但是细节上呢,可能有些不同。接下来在算法思路里面讲解:

17.2 算法思路:

 

本道题目与上一道题目的算法思路几乎一模一样,就是一些细节不一样而已。

17.3 代码演示:

//串联所有单词的子串
vector<int> findSubstring(string s, vector<string>& words) {vector<int> ret;unordered_map<string, int> hash1;//记录一下words只出现的单词的频率for (auto& e : words) hash1[e]++;int len = words[0].size();for (int i = 0; i < len; i++){unordered_map<string, int> hash2;for (int left = i, right = i, count = 0; right + len <= s.size(); right += len)//注意这个地方是right+len<=s.size(),否则到了最后就会越界。后面是加len{string in = s.substr(right, len);hash2[in]++;if (hash2[in] <= hash1[in]) count++;while (right - left + 1 > len * (words.size()))//这个地方只需要看right-left+1比words中的长度长即可证明该出窗口了{string out = s.substr(left, len);//这个只是一个下标if (hash2[out] <= hash1[out])  count--;//是有效字符hash2[out]--;left += len;}if (count == words.size())  ret.push_back(left);}}return ret;
}
int main()
{string s("barfoothefoobarman");vector<string> words = { "foo","bar" };vector<int> outcome = findSubstring(s, words);for (auto& e : outcome){cout << e << "";}cout << endl;return 0;
}

注意是加len。

17.4 总结反思:

还是得先真正的搞懂一道题目之后,才可以对类似的题目得心应手。

18. 力扣 76。最小覆盖子串

18.1 题目解析:

题目很短,也很好理解,关键就是在于怎么去找出很好的方法去解开这道题。

18.2 算法思路:

18.2.1 暴力枚举+哈希表

18.2.2 优化解法:

以上便是这道题的全部思路以及细节 ,其实还是挺复杂的。

另外还有一些需要注意:

1.能用数组的就用数组,因为数组非常的快(比容器要快)

2.一般,当只有字符的时候,可以用数组,因为字符容易找到下标,就是存储的位置,且你要是hash[26],那得减去'a',。因为只有26个位置。但要是128的话,就没必要减了,因为ascii码表也才127个值

3.字符串只能使用容器(哈希表),因为用数组,无法找到可以存储的位置。且容器还得有string,int。即unordered_map<string,int>才可以。

18.3 代码演示:

//最小覆盖子串
string minWindow(string s, string t) {int hash1[128] = { 0 };int kinds = 0;//统计一下t中的字符的种类有多少for (auto& e : t){if (hash1[e] == 0) kinds++;//如果说这个hash1[e]==0的话,说明暂时没有这个种类,则需要加上这个种类hash1[e]++;//统计t中的各个字符出现的次数}int hash2[128] = { 0 };int minlen = INT_MAX;int begin = -1;//这个是作为返回字符串的起始位置的beginfor (int left = 0, right = 0, count = 0; right < s.size(); right++){char in = s[right];hash2[in]++;//进窗口if (hash2[in] == hash1[in])  count++;while (count == kinds){if (right - left + 1 < minlen) //这个就是取出最小的长度的符合要求的字符串{minlen = right - left + 1;begin = left;//作为那个字符串的起始位置,因为后面要使用substr}char out = s[left];if (hash2[out] == hash1[out])  count--;hash2[out]--;//判断完了之后,别忘了将这个字符给题出,因为虽然说left++了,但这个毕竟是另开了一个数组,所以这个数组里面的变化也得跟着原字符串的变化,原字符串++了,那么这个数组只能踢字符了left++;}}if (begin == -1) return "";else return s.substr(begin, minlen);//这个是选取字符串,所以只能在已有的字符串中选取
}
int main()
{string s("ADOBECODEBANC");string t("ABC");string outcome = minWindow(s, t);cout << outcome << endl;return 0;
}

 18.4 总结反思:

处理好一些细节,就可以把一道题做的很好。

19 力扣 704.二分查找

在介绍这道题目之前,先来介绍一下二分算法。

二分算法,可能刚开始使用,会觉得有点难。但是你要是洞悉了二分算法的原理,其实挺简单的。

且这个算法不管数组有序还是没序。你只要找到规律之后,都可以使用二分算法的。

19.1 题目解析:

这道题算是我从写博客以来最简单的。暴力可以解决,但今天咱们讲二分算法。

 19.2 算法思路:

 

19.3 代码演示:

int search(vector<int>& nums, int target) {int left = 0; int right = nums.size() - 1;while (left <= right)//注意这个是进入循环条件{int mid = left + (right - left) / 2;if (nums[mid] < target) left = mid + 1;else if (nums[mid] > target)  right = mid - 1;else return mid;}return -1;
}
int main()
{vector<int> nums = { -1,0,3,5,9,12 };int target = 9;cout << search(nums, target) << endl;return 0;
}

这个求中间点一般是用到(right-left)/2+left。因为如果使用(left+right)/2,left+right会有溢出的风险。

19.4 总结反思:

这只是二分算法的一道开胃小菜。后面还有更大的礼物呢。 

 

 

 

 

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

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

相关文章

关于个人博客系统的测试报告

1&#xff09;项目背景2&#xff09;项目功能介绍 登陆写博客/编辑已存在博客删除博客注销 2&#xff09;基于项目功能设计相关测试用例3&#xff09;基于测试用例编写自动化测试 准备工作登陆界面相关博客首页相关博客详情页相关编辑博客相关删除博客相关注销相关 4&#xff0…

Spring Boot 与微服务详细总结

一、Spring Boot 核心概述 Spring Boot 是简化 Spring 应用开发的框架&#xff0c;作为 Spring 技术栈的整合方案和 J2EE 开发的一站式解决方案&#xff0c;其核心优势体现在&#xff1a; 快速创建独立运行的 Spring 项目&#xff0c;轻松集成主流框架内置 Servlet 容器&…

轻松上手:从零开始启动第一个 Solana 测试节点

嗨&#xff0c;各位技术爱好者们&#xff01; 大家是否对 Solana 的“光速”交易处理能力感到好奇&#xff1f;或者你是一名开发者&#xff0c;正准备在 Solana 上构建下一个杀手级 dApp&#xff1f;无论大家是出于学习目的还是实际开发需求&#xff0c;亲手运行一个 Solana 节…

Gerrit workflow

提交代码 每次提交代码前&#xff0c;先执行 git pull --rebase &#xff0c;确保已经合并天上代码&#xff0c;解决冲突 git add git commit -m git push origin HEAD:refs/for/{BRANCH_NAME} 可考虑设置 alias 方式&#xff0c;参考下文 CR-2 情况处理(verify-1情况一样处理…

量化交易如何查询CFD指数实时行情

CFD即所谓的差价合约&#xff0c;是投资者在不拥有实际资产的情况下&#xff0c;交易金融市场的一种方式。最近笔者研究这一块比较多&#xff0c;但查遍整个中文互联网却很少找到关于CFD实时行情的查询教程。因此有了这篇文章。以下我将通过一个简单的Python代码示例&#xff0…

sql练习二

首先&#xff0c;建表。创建学生表和score表接着导入创建好基础信息就可以开始做了。3、分别查询student表和score表的所有记录4、查询student表的第2条到第5条记录5、从student表中查询计算机系和英语系的学生的信息6、从student表中查询年龄小于22岁的学生信息7、从student表…

windows11下基于docker单机部署ceph集群

windows下基于docker单机部署ceph集群 创建ceph专用网络 docker network create --driver bridge --subnet 172.20.0.0/16 ceph-network查看是否创建成功&#xff08;查看创建状态&#xff09; docker network inspect ceph-network拉取镜像&#xff1a;(镜像源自行选择) docke…

使用DataGrip连接安装在Linux上的Redis

目录 一、前言 二、开放防火墙端口 三、使用DataGrip连接安装在Linux上的Redis 一、前言 在学习黑马Redis从入门到实战的视频&#xff0c;完成了Redis在linux上的安装配置之后&#xff0c;我们可以使用图形化界面方便操作使用redis数据库。在24年JavaWebAI学习时连接MySQL数…

MySQL的union、union all导致排序失效

今天练习SQL&#xff0c;使用union all 连接各个查询导致我的各个查询排序失效&#xff0c;最后发现使用union all后会忽略各个模块的order by&#xff0c;只有最外层的order by才会生效原SQL如下&#xff1a;( selectexam_id tid,count(distinct uid) uv, count(uid) pv frome…

LVS 集群技术实践:NAT 与 DR 模式的配置与对比

1 实验环境规划 实验目标是搭建一个负载均衡集群&#xff0c;通过 LVS 调度器将流量分发到两台真实服务器&#xff08;RS1 和 RS2&#xff09;。2.网络配置3 实验步骤关闭防火墙和 SELinux安装 HTTP 服务&#xff08;在 RS21和 RS2 上&#xff09;&#xff1a;sudo systemctl s…

YOLOv8中添加SENet注意力机制

注意力机制(Attention Mechanism)是深度学习中的一种方法,在图像处理领域,尤其是在卷积神经网络(CNN)和视觉Transformer等架构中。图像数据具有局部相关性,注意力机制可以帮助模型聚焦于图像中更重要的区域,从而提升处理效果。 SENet(Squeeze-and-Excitation Network)…

SpringBoot五分钟快速入门指南

使用 Spring Boot 构建应用 本指南提供了关于Spring Boot如何帮助您加速应用开发的一些示例。随着您阅读更多 Spring 入门指南,您将看到 Spring Boot 的更多用例。本指南旨在让您快速了解 Spring Boot。如果您想创建自己的基于 Spring Boot 的项目,请访问 Spring Initializr…

docker,防火墙关闭后,未重启docker,导致端口映射失败

首先&#xff0c;看这篇文章前&#xff0c;建议先把网上其他的文章说的方法尝试一遍&#xff01;&#xff01;&#xff01; 1. 现象 docker启动某一个容器&#xff0c;然后映射端口时显示失败2. 解决 把网上的方法尝试一遍之后&#xff0c;最后发现是防火墙的问题&#xff01;&…

事务处理与AOP(web后端笔记第四期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录事务spring事物管理事物属性--回滚事物属性--传播行为(propagation)AOP一些核心概念通知类型通知的执行顺序切入点表达式executionannotation连接点事务 事物是一组操作的集合&…

第36周———— RNN实现阿尔茨海默病诊断

目录 前言 1.检查GPU 2.查看数据 3.划分数据集 4.创建模型与编译训练 ​​​​5.编译及训练模型 6.结果可视化 7.模型预测 8.总结&#xff1a; 前言 &#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 1.检查G…

equals和hashcode方法重写

在 Java 中&#xff0c;当你需要基于对象的内容而非引用地址来判断两个对象是否相等时&#xff0c;就需要重写equals和hashCode方法。以下是具体场景和实现原则&#xff1a;一、为什么需要同时重写这两个方法&#xff1f;equals方法&#xff1a;默认比较对象的内存地址&#xf…

Excel批量生成SQL语句 Excel批量生成SQL脚本 Excel拼接sql

Excel批量生成SQL语句 Excel批量生成SQL脚本 Excel拼接sql一、情境描述在Excel中有标准的格式化数据&#xff0c;如何快速导入到数据库中呢&#xff1f;有些工具支持Excel导入的&#xff0c;则可以快速导入数据---例如Navicat&#xff1b;如果不支持呢&#xff0c;如果将Excel表…

金和OA C6 DelTemp.aspx 存在XML实体注入漏洞(CVE-2025-7523)

免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。 前言:我们建立了一个更多,更全的知识库。每日追踪最新的安全漏洞,追中25HW情报。 更多详情: http…

Android性能优化之启动优化

一、启动性能瓶颈深度分析 1. 冷启动阶段耗时分布阶段耗时占比关键阻塞点进程创建15%fork进程 加载ZygoteApplication初始化40%ContentProvider/库初始化Activity创建30%布局inflate 视图渲染首帧绘制15%VSync信号等待 GPU渲染2. 高频性能问题 初始化风暴&#xff1a;多个库…

中国优秀开源软件及企业调研报告

中国优秀开源软件及企业调研报告 引言 当前中国开源生态呈现蓬勃发展态势&#xff0c;技术创新领域尤为活跃&#xff0c;其中人工智能大模型成为开源动作的核心聚焦方向。2025年上半年&#xff0c;国内AI领域开源生态迎来密集爆发&#xff0c;头部科技企业相继推出重要开源举…