《算法闯关指南:优选算法--滑动窗口》--09长度最小的子数串,10无重复字符的最长字串

《算法闯关指南:优选算法--滑动窗口》--09长度最小的子数串,10无重复字符的最长字串
🔥个人主页:@草莓熊Lotso

🎬作者简介:C++研发方向学习者

📖个人专栏:《C++知识分享》《Linux 入门到实践:零基础也能懂》《数据结构与算法》《测试开发实战指南》《算法题闯关指南》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。

前言:聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“局部最优”到“全局最优”的思路,解决区间调度等问题 内容以题带点,讲解思路与代码实现,帮助大家快速提升代码能力


目录

09.长度最小的子数串

解法一:(暴力求解)(会超时)

算法思路:

解法二:(滑动窗口)

算法思路:

C++代码演示:

算法总结&&笔记展示:

10.无重复字符的最长字串

解法一:(暴力求解)(不会超时,可以通过):

算法思路:

解法二:(滑动窗口)

算法思路:

C++代码演示:

算法总结&&笔记展示:


09.长度最小的子数串

题目链接:

209. 长度最小的子数组 - 力扣(LeetCode)

题目描述:

题目示例:

解法一:(暴力求解)(会超时)

算法思路:

【从前往后】枚举数组中的任意一个元素,把它当成起始位置。然后从这个【起始位置】开始,然后寻找一段最短的区间,使得这段区间的和【大于等于】目标值。

将所有元素作为起始位置所得的结果中,找到【最小值】即可。

--代码这里就不演示了

解法二:(滑动窗口)

算法思路:

由于此问题分析的对象是【一段连续的区间】,因此可以考虑【滑动窗口】的思想来解决这道题。

让滑动窗口满足:从 i 位置开始,窗口内所有的和小于 target (那么当窗口内元素之和第一次大于等于目标值的时候,就是 i 位置开始,满足条件的最小长度)。

做法:将右端元素划入窗口之中,统计出此时窗口内元素的和:

  • 如果窗口内元素之和大于 target :更新结果,并且将左端元素划出去的同时继续判断是否满足条件并更新结果(因为左端元素可能很小,划出去之后依旧满足条件)
  • 如果窗口内元素之和不满足条件:right++,另下一个元素进入窗口。

相信科学(这也是很多题解以及帖子没告诉你的事情:只给你说怎么做,没给你解释为什么这么做):

为何滑动窗口可以解决问题,并且时间复杂度更低?

这个窗口寻找的是:以当前窗口最左侧元素(记为 left1)为基准,符合条件的情况。也就是在这道题中,从 left1 开始,满足区间和 sum>=target 时的最右侧(记为 right1)能到哪里。

我们既然已经找到从 left1 开始的最优的区间,那么就可以大胆舍去 left1。但是如果继续像方法一一样,重新开始统计第二个元素(left2)往后的和,势必会有大量重复的计算(因为我们在求第一段区间的时候,已经算出很多元素的和了,这些和是可以在计算下次区间和的时候用上的)。

此时,right1的作用就体现出来了,我们只需要将 left1 这个值从 sum  中剔除。从 right1 这个元素开始,往后找满足 left2 元素的区间 (此时 right1 也有可能是满足的,因为 left1 可能很小。sum 剔除掉 left1 之后,依旧满足大于等于 target )。这样我们就能省掉大量重复的计算。

  • 这样我们不仅能解决问题,效率也会大大提升。

时间复杂度:虽然代码是两层循环,但是我们的 left 指针和 right 指针都是不回退的,两者最多都往后移动 n 次。因此时间复杂度是 O(N)

C++代码演示:

class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int n=nums.size(),sum=0,len=INT_MAX; for(int left=0,right=0;right<n;right++) { sum+=nums[right];//进窗口 while(sum>=target) { len=min(len,right-left+1);//更新结果 sum-=nums[left++];//出窗口 } } return len==INT_MAX?0:len; } };

算法总结&&笔记展示:

笔记的字有点丑,大家见谅:


10.无重复字符的最长字串

题目链接:

3. 无重复字符的最长子串 - 力扣(LeetCode)

题目描述:

题目示例:

解法一:(暴力求解)(不会超时,可以通过):

算法思路:

枚举【从每一个位置】开始往后,无重复字符的子串可以到达什么位置。找到其中长度最大的即可。

在往后寻找无重复子串能到达的位置时,可以利用【哈希表】统计出字符出现的频次,来判断什么时候子串出现了重复元素。

解法二:(滑动窗口)

算法思路:

研究的对象依旧是一段连续的区间,因此继续使用【滑动窗口】思想来优化。

让滑动窗口满足:窗口内所有元素都是不重复的。

做法:右端元素 ch 进入窗口的时候,哈希表统计这个字符的频次:

  • 如果这个字符出现的频次超过 1 ,说明窗口内有重复元素,那么就从左侧开始划出窗口,直到 ch 这个元素的频次变为 1,然后再更新结果。
  • 如果没有超过 1,说明当前窗口没有重复元素,可以直接更新结果

C++代码演示:

class Solution { public: int lengthOfLongestSubstring(string s) { int hash[128]={0};//数组模拟实现hash表 int left=0,right=0,ret=0; int n=s.size(); while(right<n) { hash[s[right]]++; while(hash[s[right]]>1) { hash[s[left++]]--; } ret=max(ret,right-left+1); right++; } return ret; } };

算法总结&&笔记展示:

笔记的字有点丑,大家见谅:


往期回顾:

《算法闯关指南:优选算法-双指针》--01移动零,02复写零

《算法闯关指南:优选算法-双指针》--03快乐数,04盛水最多的容器

《算法闯关指南:优选算法-双指针》--05有效三角形的个数,06查找总价值为目标值的两个商品

《算法闯关指南:优选算法-双指针》--07三数之和,08四数之和

结语:本篇博客介绍了两个滑动窗口算法实战题解:209.长度最小的子数组和3.无重复字符的最长子串。针对第一题,通过暴力解法和滑动窗口对比,详细解释了滑动窗口的高效原理,即通过左右指针不回退降低时间复杂度。第二题同样采用滑动窗口,利用哈希表统计字符频次来检测重复。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

Read more

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题 在开发 Web 应用时,尤其是集成了 Unity WebGL 内容的页面,遇到一个问题:当 Unity WebGL 渲染内容嵌入到一个 Tab 中时,切换 Tab 后画面会变黑,直到用户点击黑屏区域,才会恢复显示。 这个问题通常是因为 Unity 渲染在 Tab 切换时被暂停或未能获得焦点所致。 在本文中,我们将介绍如何在使用 Layui 框架时,通过监听 Tab 切换事件并强制 Unity WebGL 渲染恢复,来解决这一问题。 1. 问题描述 当 Unity WebGL 内容嵌入到页面中的多个

By Ne0inhk
深度优先的艺术:探索二叉树的深搜算法精髓

深度优先的艺术:探索二叉树的深搜算法精髓

文章目录 * 前言 * ☀️一、计算布尔二叉树的值 * 🌙解法 * ⭐代码 * ☀️二、求根节点到叶节点数字之和 * 🌙解法 * ⭐代码 * ☀️三、二叉树剪枝 * 🌙解法 * ⭐代码 * ☀️四、验证二叉搜索树 * 🌙解法 * ☁️步骤 * ⭐代码 * ☀️五、二叉搜索树中第k小的元素 * 🌙解法 * ☁️步骤 * ⭐代码 * 🌀时间和空间复杂度分析 * ☀️六、二叉树的所有路径 * 🌙解法 * ☁️步骤 * ⭐代码 * 🌀时间复杂度分析 * 结语 前言 二叉树作为一种重要的数据结构,在算法领域有着广泛的应用,而深度优先搜索(DFS)是二叉树遍历和操作的核心算法之一。通过 DFS,可以以递归或迭代的方式深入探索树的每一个节点,并高效地解决路径查找、节点计数、最大深度等问题。在这篇文章中,我们将深入剖析二叉树的深搜算法,从基础概念到典型应用,再到代码实

By Ne0inhk

SHA-256哈希验证程序

一、 程序功能总览 该程序的核心功能是交互式地验证一个给定的SHA-256哈希值是否与一个给定的明文口令的哈希值相匹配。它是一个用于教学、演示或简单校验的命令行工具。 核心价值:用户不需要手动计算SHA-256哈希值,只需要将“密文:明文”格式的字符串提供给程序,程序会自动计算明文的哈希值,并与提供的“密文”进行比对,直观地返回验证结果。 功能细分: 1. 输入处理:接收用户通过标准输入(命令行)提供的字符串。 2. 格式校验:检查输入字符串是否符合预定义的“哈希值:明文”格式。如果不符合,会给出清晰的错误提示。 3. 哈希计算:使用Python标准库的hashlib模块,对输入的明文部分进行SHA-256哈希计算。 4. 结果比对:将计算得到的哈希值与用户提供的哈希值进行逐字符比对。 5. 结果展示:以清晰、格式化的方式向用户展示验证的输入、过程输出和最终结果(成功或失败)。 6. 交互循环:程序提供了一个主循环,允许用户连续进行多次验证,直到主动输入退出指令(如quit, exit,

By Ne0inhk
【动态规划】P11188 「KDOI-10」商店砍价|普及+

【动态规划】P11188 「KDOI-10」商店砍价|普及+

本文涉及知识点 C++动态规划 P11188 「KDOI-10」商店砍价 题目背景 English Statement. You must submit your code at the Chinese version of the statement. 您可以点击 这里 下载本场比赛的选手文件。 You can click here to download all tasks and examples of the contest. 密码 / Password:rAnHoUyaSuoBaoMimaNijuEdefAngsHa2)2$1)0(2@0! 本场比赛所有题目从标准输入读入数据,输出到标准输出。 题目描述 有一个正整数 n

By Ne0inhk