3数组-滑动窗口-长度最小的子数组/ 水果成篮/最小覆盖子串/替换后的最长重复字符

本文主要是介绍3数组-滑动窗口-长度最小的子数组/ 水果成篮/最小覆盖子串/替换后的最长重复字符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3] 输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:

输入:target = 4, nums = [1,4,4] 输出:1
示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:sum=0n=len(nums)res=n+1j=0#i是右指针 j左指针for i in range(0,n):sum+=nums[i]# 如果sum持续大于target 就不右移扩大窗口 而是左移缩小窗口while(sum>=target):# 因为满足sum>=target 所以更新当前区间长度res=min(res,i-j+1)sum-=nums[j]j+=1#跳出循环 说明sum不满足>=target 所以需要继续移动右指针# 如果res没有被赋值 则返回0if res==n+1:return 0else:return res

904. 水果成篮

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

示例 1:

输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。
示例 2:

输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
示例 3:

输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。
如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:

输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:可以采摘 [1,2,1,1,2] 这五棵树。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fruit-into-baskets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:freq数组记录现在窗口中两种水果的数目,count记录现在窗口中有多少种不同的水果,如果count<=2,那么right指针可以一直向右移动,直到count>2,当count>2时,说明窗口中的水果种类超过2,为了减少水果种类,left指针就要向右移动,移动的同时还要更新freq数组,最后取最大值即可。

模板
def findSubArray(nums):N = len(nums) # 数组/字符串长度left, right = 0, 0 # 双指针,表示当前遍历的区间[left, right],闭区间sums = 0 # 用于统计 子数组/子区间 是否有效,根据题目可能会改成求和/计数res = 0 # 保存最大的满足题目要求的 子数组/子串 长度while right < N: # 当右边的指针没有搜索到 数组/字符串 的结尾sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数while 区间[left, right]不符合题意:# 此时需要一直移动左指针,直至找到一个符合题意的区间sums -= nums[left] # 移动左指针前需要从counter中减少left位置字符的求和/计数left += 1 # 真正的移动左指针,注意不能跟上面一行代码写反# 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串res = max(res, right - left + 1) # 需要更新结果right += 1 # 移动右指针,去探索新的区间return res作者:fuxuemingzhu
链接:https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/fen-xiang-hua-dong-chuang-kou-mo-ban-mia-f76z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def totalFruit(self, fruits: List[int]) -> int:# 本质上是 最多包含两个不同字符的最长连续字串left=0n=len(fruits)# freq 计算每种类出现的频次 count计算品种数量# freq 相当于hash表 长度要是len和max(fruit)的最大值 防止出现[1,2,3,3,46]这种freq=[0]*max(max(fruits),n)count=0res=0for right in range(0,n):freq[fruits[right]]+=1#说明第一次加入该品种 种类加1if freq[fruits[right]]==1:count += 1# 品种种类大于2 移动左指针 缩小窗口while(count>2):#一直减少左指针指向的品种 直到该品种数量为0 则种类减1freq[fruits[left]]-=1if freq[fruits[left]]==0:count-=1left+=1#更新区间res=max(res,right-left+1)return res

1004. 最大连续1的个数 III

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

示例 1:

输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2 输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1] 粗体数字从 0 翻转到 1,最长的子数组长度为 6。 示例 2:

输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3 输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1] 粗体数字从 0 翻转到 1,最长的子数组长度为 10。

class Solution(object):def longestOnes(self, nums, k):""":type nums: List[int]:type k: int:rtype: int"""# 本质是确保窗口内0的个数小于等于k个left,right=0,0res=0# 分别计算0,1的个数count=[0,0]n=len(nums)while(right<n):count[nums[right]]+=1# 如果0的个数大于k 则移动左窗口到保持在窗口内0的个数为k的程度while(count[0]>k):count[nums[left]]-=1left+=1#跳出循环 说明此时窗口内0的数量等于k 更新窗口res=max(res,right-left+1)right+=1return res

76. 最小覆盖子串

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

注意:

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

示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC” 输出:“BANC”
示例 2:

输入:s = “a”, t = “a” 输出:“a”
示例 3:

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

class Solution:def minWindow(self, s: str, t: str) -> str:need = collections.defaultdict(int)for c in t:need[c] += 1needCnt = len(t)i = 0 #记录起始位置res = (0, float('inf'))  #用两个元素,方便之后记录起终点#三步骤:#1. 增加右边界使滑窗包含tfor j,c in enumerate(s):# 大于0说明是串t需要的元素,且s中也有,随着右滑,所以【真正】需要的元素个数--if need[c] >0:needCnt -= 1#随着右滑,【所有】需要的元素--need[c] -= 1 #这行放在外面不可以,看19行 need[c] == 0#2. 收缩左边界直到无法再去掉元素   !注意,处理的是i#needCnt == 0 说明已经右滑到了包含t的所有元素if needCnt == 0:while True:c = s[i]if need[c] == 0: #表示再去掉就不行了(need>0)breakelse:need[c] += 1i += 1# 跳出了循环,更新结果if j-i < res[1] - res[0]:  #这里是否减一都可以,只要每次都是这样算的就行,反正最后也是输出子串而非长度res = (i,j)#3. i多增加一个位置,准备开始下一次循环(注意这步是在 needCnt == 0里面进行的 )# 此时need[s[i]]=need[c]==0 所以是满足条件的,所以要准备下一次移动了,所以现在要去掉need[s[i]],然后继续右滑need[s[i]] += 1needCnt += 1    #由于 移动前i这个位置 一定是所需的字母,因此NeedCnt才需要+1i += 1return "" if res[1]>len(s) else s[res[0]: res[1]+1]

题解参考:https://leetcode-cn.com/problems/minimum-window-substring/solution/tong-su-qie-xiang-xi-de-miao-shu-hua-dong-chuang-k/

424. 替换后的最长重复字符

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。

在执行上述操作后,返回包含相同字母的最长子字符串的长度。

示例 1:

输入:s = “ABAB”, k = 2 输出:4 解释:用两个’A’替换为两个’B’,反之亦然。
示例 2:

输入:s = “AABABBA”, k = 1 输出:4 解释:
将中间的一个’A’替换为’B’,字符串变为 “AABBBBA”。
子串 “BBBB” 有最长重复字母, 答案为 4。

class Solution(object):def characterReplacement(self, s, k):""":type s: str:type k: int:rtype: int"""# 本质上是这个窗口内出现次数最多的那个字符之外  的其余字符之和不大于kcount = collections.Counter()left = 0res = 0nums = list(s)for right, x in enumerate(nums):count[x] += 1# 当前区间长度-出现次数最多的那个字符的次数=其他字符 >k 则移动左指针while ((right - left + 1)-max(count.values()) > k):count[nums[left]] -= 1# if (count[nums[left]] == 0):#     del count[nums[left]]left+=1res = max(res, right - left + 1)return res'''"ABABCCC"2'''

3最长无重复子串

https://leetcode.cn/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-nifty-snyder0f5-0auy/

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:left,right = 0,0res = 0if len(s) == 0:return 0if s.count(s[0]) == len(s):return 1if len(set(s)) == len(s):return len(s)while right < len(s):if s[right] not in s[left:right]:right +=1res = max(res,len(s[left:right]))else:while s[right] in s[left:right]:left +=1return res作者:nifty-snyder0f5
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-nifty-snyder0f5-0auy/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。``````python
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:n = len(s)left,right = 0,0res = 0 # 子串长度while right<n:# 不满足区间的要求 左指针移动while s[right] in s[left:right]:left +=1 # 左指针右移# 满足区间长度 更新res和右指针移动res = max(res,right-left+1)right+=1return res

这篇关于3数组-滑动窗口-长度最小的子数组/ 水果成篮/最小覆盖子串/替换后的最长重复字符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/697793

相关文章

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

Python批量替换多个Word文档的多个关键字的方法

《Python批量替换多个Word文档的多个关键字的方法》有时,我们手头上有多个Excel或者Word文件,但是领导突然要求对某几个术语进行批量的修改,你是不是有要崩溃的感觉,所以本文给大家介绍了Py... 目录工具准备先梳理一下思路神奇代码来啦!代码详解激动人心的测试结语嘿,各位小伙伴们,大家好!有没有想

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro