【优选算法必刷100题】第009~010题(滑动窗口):长度最小的子数串、无重复字符的最长字串

【优选算法必刷100题】第009~010题(滑动窗口):长度最小的子数串、无重复字符的最长字串

🔥个人主页:Cx330🌸

❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》《优选算法指南-必刷经典100题》

🌟心向往之行必能至


🎥Cx330🌸的简介:


目录

09.长度最小的子数串

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

算法思路:

解法二:(滑动窗口)

算法思路:

C++代码演示:

算法总结&&笔记展示:

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

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

算法思路:

解法二:(滑动窗口)

算法思路:

C++代码演示:

算法总结&&笔记展示:


09.长度最小的子数串

题目链接:

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

题目描述:

题目示例:

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

算法思路:

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

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

--代码这里就不演示了

解法二:(滑动窗口)

算法思路:

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

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

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

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

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

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

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

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

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

时间复杂度:虽然代码是两层循环,但是我们的 left 指针和 right 指针都是不回退的,两者最多都往后移动 次。因此时间复杂度是 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}; int n=s.size(),left=0,right=0,ret=0; while(right<n) { hash[s[right]]++; while(hash[s[right]]>1) { hash[s[left++]]--; } ret=max(ret,right-left+1); right++; } return ret; } };
算法总结&&笔记展示:

博主笔记(字迹有点丑,请大家见谅):


往期回顾:

【优选算法必刷100题】第001~002题(双指针算法):移动零、复写零问题

【优选算法必刷100题】第003~004题(双指针算法):快乐数和盛水最多的容器

【优选算法必刷100题】第005~006题(双指针算法):有效三角形的个数和查找总价值为目标值的两个商品

【优选算法必刷100题】第007~008题(双指针算法):三数之和,四数之和

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

Read more

Java字符串算法核心攻略

Java字符串算法核心攻略

Java字符串算法核心攻略 提示:在 ASCII 码(美国信息交换标准代码)中,大小写英文字母和数字的十进制数值范围如下: * 大写字母 (A - Z):65 到 90 * ‘A’ 是 65 * ‘Z’ 是 90 * 小写字母 (a - z):97 到 122 * ‘a’ 是 97 * ‘z’ 是 122 * 数字是 (0-9):48 到 57 * ‘0’ 是 48 * ‘9’ 是 57 一、必会的字符串方法 刷题前先把这些方法练熟,后面会反复用到。 1.

By Ne0inhk
【动态规划】买卖股票相关问题

【动态规划】买卖股票相关问题

一、买卖股票的最佳时机含手续费 714. 买卖股票的最佳时机含手续费 题目描述: 题目分析: 1、状态分析 其实一共就只有两种状态,不是处于 持有 状态,就是处于 未持有 状态。 * f[i]表示第i天结束后,处于 持有 状态时,最大的利润 * g[i]表示第i天结束后,处于 未持有 状态时,最大的利润 2、状态转移方程 对于f[i],有两种情况可以到达这种状态: * 在第 i-1 天时就已处于 持有 状态,然后第 i 天啥也不干,仍然保持 持有 状态。此时的最大利润就为 f[i - 1]

By Ne0inhk
从冒泡到模拟q sort函数——初见排序算法的探索和思考

从冒泡到模拟q sort函数——初见排序算法的探索和思考

国庆中秋喜相连,万家团圆乐同庆。 各位小伙伴们大家好,我是此方,在此,先祝大家双节快乐! 我们都知道排序有很多种:例如冒泡排序,插入排序,快速排序,等等很多种。 而冒泡排序,是各种计算机语言中最经典的一种排序算法。 今天我将从冒泡排序开始,到实现qsort函数的模拟。逐层深入,探索排序问题。 并给出鄙人的一些拙见。 上正文: 一,冒泡排序:最经典的排序算法 假如有一个十元素整型数组,他是完全倒着排序的:就像这样 now,我们要按照从小到大的顺序将这十个数字重新排列。 如果我们想要用冒泡排序:那么他的逻辑应该是这样的: 首先让最左边的数字和他右边的数字比较:9>8,将9和8互换位置: 让9继续和他右边的数字比较,再互换位 以此类推:9不断的比较——>移动——>再比较:最后;会到达最右边,这样,我们就让最大的数字9放在了最低位置 然后是8,接下来是7,6,5.

By Ne0inhk
算法思想之深度优先搜索(DFS)、递归以及案例(最多能得到多少克黄金、精准核酸检测、最富裕的小家庭)

算法思想之深度优先搜索(DFS)、递归以及案例(最多能得到多少克黄金、精准核酸检测、最富裕的小家庭)

深度优先搜索(DFS)、递归 * 深度优先搜索(Depth First Search,DFS)是一种用于遍历或搜索树或图的算法。在 DFS 算法中,从起始节点开始,沿着一条路径尽可能深地访问节点,直到到达叶子节点或者无法继续前进为止。然后退回到最近的一个有未探索节点的分支节点,继续探索其他路径,直到所有节点都被访问过为止。 * 深度优先搜索常常用于解决以下类型的问题:深度优先搜索是一种简单而强大的算法,可以解决许多实际问题。 * 图遍历:在无向图或有向图中寻找特定节点之间的路径、判断图的连通性等。 * 连通性问题:判断图中是否存在环、判断图的强连通分量等。 * 组合问题:生成排列、组合或子集等组合型问题。 * 寻路问题:求解从起始点到目标点的最短路径或所有可行路径。 * 递归问题:通过递归实现深度优先搜索,例如二叉树的遍历等。 小华最多能得到多少克黄金 * 题目描述小华按照地图去寻宝,地图上被划分成 m 行和 n 列的方格,横纵坐标范围分别是 [0, n-1] 和 [0, m-1]。在横坐标和纵坐标的数位之和不大于 k

By Ne0inhk