leetcode 滑动窗口小结 (二)

目录

  • 424. 替换后的最长重复字符
    • 思考分析1
    • 优化
  • 1004. 最大连续1的个数 III
    • 友情提醒
    • 方法1,基于当前最大频数
    • 方法2,基于历史最大频数

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

https://leetcode-cn.com/problems/longest-repeating-character-replacement/
给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

注意:
字符串长度 和 k 不会超过 10^4。
示例 1:

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

示例 2:

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

思考分析1

需要注意的地方:

1、何时扩充窗口?
当子串符合要求,向右扩充一位。(贪心思想,满足了要求还要继续膨胀)
2、子串达成什么条件能说明符合要求?
如果最大频数 + k >= 当前窗口长度,(也就是说经过k此修改,我们可以将不是出现次数最多的元素修改为频数最高元素,从而变为重复串,并且这个串的长度是大于此时窗口长度的)那么我们认为是符合条件的,此时更新窗口长度,取历史窗口长度与当前窗口长度的较大值
3、什么时候滑动窗口
当子串不满足条件的时候,窗口整体向右滑动一位,窗口长度不会减少。

class Solution {
public:int characterReplacement(string s, int k) {int left = 0, right = 0;//当前窗口中元素的最高频数int now_max_freq = 0;int hash_map[26] ={0};//窗口长度最大值int max_window_length = 0;while(right < s.size()){//新加入窗口的元素char c = s[right];//窗口内这个元素对应的频数+1hash_map[c - 'A']++;//找到整个窗口内最大频数for(int i = 0; i < 26; i++)now_max_freq = max(now_max_freq,hash_map[i]);//如果最大频数 + k >= 当前窗口长度,那么我们认为是符合条件的,此时更新窗口长度,取历史窗口长度与当前窗口长度的较大值if(now_max_freq + k >= right - left + 1){max_window_length = max(max_window_length,right - left + 1);}//如果不满足整个条件,我们需要将整个窗口平移else{char d = s[left];hash_map[d - 'A']--;left++;}right++;}return max_window_length;}
};

优化

关于优化,首先得知道一点就是我们之前更新窗口长度的条件:
1、先找这个窗口内的最大频数
2、如果这个频数 + k >= 当前窗口长度,我们选择更新窗口长度
由于在寻找最大频数的时候有个比较过程,并且每次新进来一个字符我们就得重新比较26次。(我们可以优化比较,例如加入备忘录什么的)。但这里我们不需要这样做。
我们只需要找到“历史窗口内元素出现最大频数”,然后观察这个频数 + k 是否 >= 当前窗口长度。
由于这道题目要求求解的是最长重复子串,如果当前窗口最大字符重复个数小于历史窗口的最大字符重复个数,完全可以将此窗口忽略掉,因为它必然不可能是最长重复子串。只有当历史窗口的最大字符重复个数更新时,其最大长度才会进行相应的更新。
现在我们将上面的代码稍作修改,改成如下代码:

class Solution {
public:int characterReplacement(string s, int k) {int left = 0, right = 0;//历史最大频数int history_max_freq = 0;int hash_map[26] ={0};int max_window_length = 0;while(right < s.size()){//新加入窗口的元素char c = s[right];hash_map[c - 'A']++;//观察整个元素是不是窗口内出现次数最多的元素,如果是更新history值history_max_freq = max(history_max_freq,hash_map[c - 'A']);if(history_max_freq + k >= right - left + 1){max_window_length = max(max_window_length,right - left + 1);}else{char d = s[left];//窗口左移,被移除的元素在窗口内频数-1hash_map[d - 'A']--;left++;}right++;}return max_window_length;}
};

两种解法性能相差挺大的。
在这里插入图片描述
下面一题和本题几乎一模一样,甚至是简化,我们也同样用两种思路来做吧。

1004. 最大连续1的个数 III

https://leetcode-cn.com/problems/max-consecutive-ones-iii/
给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。

返回仅包含 1 的最长(连续)子数组的长度。
示例 1:

输入:A = [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:

输入:A = [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。

友情提醒

由于这一题的简化性,最好好好看看两者代码有何区别,不然以为是一样的。(其实性能应该差不多,因为这里在找当前最大频数的时候不需要比较26次了,只需要一次。)

方法1,基于当前最大频数

class Solution {
public:int longestOnes(vector<int>& A, int K) {int left = 0, right = 0;int one_times = 0;int now_max_freq = 0;int max_window_length = 0;while(right < A.size()){int c = A[right];if(c == 1) one_times++;if(one_times + K >= right - left + 1){max_window_length = max(max_window_length,right - left + 1);}else{int d = A[left];if(d == 1) one_times--;left++;}right++;}return max_window_length;}
};

方法2,基于历史最大频数

class Solution {
public:int longestOnes(vector<int>& A, int K) {int left = 0, right = 0;int one_times = 0;int history_max_freq = 0;int max_window_length = 0;while(right < A.size()){int c = A[right];if(c == 1) one_times++;history_max_freq = max(history_max_freq,one_times);if(history_max_freq + K >= right - left + 1){max_window_length = max(max_window_length,right - left + 1);}else{int d = A[left];if(d == 1) one_times--;left++;}right++;}return max_window_length;}
};

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

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

相关文章

软件故障_一些主要的软件故障

软件故障The need for software engineering was realized by the software industry after some of its major failures. Some of these failures are listed below, 在经历了一些重大失败之后&#xff0c;软件行业意识到了对软件工程的需求 。 下面列出了其中一些故障&#x…

十五、修改VGG16网络来适应自己的需求

一、VGG-16 VGG-16神经网络是所训练的数据集为ImageNet ImageNet数据集中验证集和测试集一万五千张&#xff0c;有一千个类别 二、加载VGG-16神经网络模型 VGG16模型使用说明 torchvision.models.vgg16(pretrainedFalse) 其中参数pretrained表示是否下载已经通过ImageNet数…

leetcode 滑动窗口小结 (三)

目录978. 最长湍流子数组题目思路分析以及代码1052. 爱生气的书店老板题目思考分析与初步代码优化思路以及优化代码1208. 尽可能使字符串相等题目思考分析以及代码978. 最长湍流子数组 https://leetcode-cn.com/problems/longest-turbulent-subarray/ 题目 当 A 的子数组 A[…

JAVA多线程学习3--线程一些方法

一、通过sleep方法睡眠 在指定的毫秒数内让当前正在执行的线程休眠&#xff08;暂停执行&#xff09;。该线程不丢失任何监视器的所属权。 二、线程优先级 线程具有优先级&#xff0c;范围为1-10。 MAX_PRIORITY线程可以具有的最高优先级。int类型&#xff0c;值为10. MIN_PRIO…

mcq 队列_MCQ | 量子密码学

mcq 队列1) Which possible Attacks in Quantum Cryptography can take place? 1)量子密码术中可能发生哪些攻击&#xff1f; Possible Attacks in Quantum Cryptography and Birthday Attack 量子密码术和生日攻击的可能攻击 Birthday attack and Boomerang attack 生日袭击…

《inside the c++ object model》读书笔记 之一:对象

关于对象 ...引子:在C语言中,"数据"和"处理数据的操作(函数)"是分开来声明的,语言本身并没有支持"数据和函数"之间关联性,这种程序成为"程序性的",由一组"分布在各个一功能为向导的函数中"的算法驱动,他们处理的是共同的外部…

十六、保存和加载自己所搭建的网络模型

一、保存自己搭建的模型方法一 例如&#xff1a;基于VGG16网络模型架构的基础上加上了一层线性层&#xff0c;最后的输出为10类 torch.save(objmodule,f"path")&#xff0c;传入需要保存的模型名称以及要保存的路径位置 保存模型结构和模型的参数&#xff0c;保存文…

uC/OS-II OS_TASK.C中有关任务管理的函数

函数大致用途 OS_TASK.C是uC/OS-II有关任务管理的文件&#xff0c;它定义了一些函数&#xff1a;建立任务、删除任务、改变任务的优先级、挂起和恢复任务&#xff0c;以及获取有关任务的信息。 函数用途OSTaskCreate()建立任务OSTaskCreateExt()扩展建立任务OSTaskStkChk()堆…

windows下写的脚本,在linux下执行失败

Windows中的换行符为CRLF, 即正则表达式的rn(ASCII码为13和10), 而Unix(或Linux)换行符为LF, 即正则表达式的n. 在Windows和Linux下协同工作的时候, 往往这个细小的差别就导致问题, 如 1)Windows下写的Shell脚本, 在Linux下运行时往往出现rn是无效参数, 不能执行; 2)vi 等编器下…

Scala中的do ... while循环

做...在Scala循环 (do...while loop in Scala) do...while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an exit condition. If this condition is TRUE the code will run otherwise it runs the first …

十七、完整神经网络模型训练步骤

以CIFAR-10数据集为例&#xff0c;训练自己搭建的神经网络模型架构 一、准备CIFAR-10数据集 CIFAR10官网使用文档 torchvision.datasets.CIFAR10(root"./CIFAR_10",trainTrue,downloadTrue) 参数描述root字符串&#xff0c;指明要下载到的位置&#xff0c;或已有数…

μC/OS-Ⅱ 操作系统内核知识

目录μC/OS-Ⅱ任务调度1.任务控制块2.任务管理3.任务状态μC/OS-Ⅱ时间管理μC/OS-Ⅱ内存管理内存控制块MCBμC/OS-Ⅱ任务通信1.事件2.事件控制块ECB3.信号量4.邮箱5.消息队列操作系统内核&#xff1a;在多任务系统中&#xff0c;提供任务调度与切换、中断服务 操作系统内核为每…

第二版tapout

先说说上次流回来的芯片的测试情况。 4月23日&#xff0c; 芯片采用裸片直接切片&#xff0c; bond在板子上&#xff0c;外面加了一个小塑料壳来保护&#xff0c;我们就直接拿回来测试了。 测试的主要分为模拟和数字两部分&#xff0c; 数字部分的模块基本都工作正常&#xff0…

cd-rom门锁定什么意思_CD-ROM的完整形式是什么?

cd-rom门锁定什么意思CD-ROM&#xff1a;光盘只读存储器 (CD-ROM: Compact Disc Read-Only Memory) CD-ROM is an abbreviation of "Compact Disc Read-Only Memory". It is a data storage memory in the form of an optical compact disc, which is read by a syst…

远程工作时的协作工具

远程工作时的协作工具 Google Hangout 用于日常会议和面对面交谈,在国内其实可以用qq来带起。Campfire 用于一天来的持续对话。Screenhero 用于分享屏幕&#xff0c;一起写代码,这个比较有用,可以一起写代码。Balsamiq 用于计划要制作的 UI。Asana 用于管理任务Google Docs 用于…

十八、完整神经网络模型验证步骤

网络训练好了&#xff0c;需要提供输入进行验证网络模型训练的效果 一、加载测试数据 创建python测试文件&#xff0c;beyond_test.py 保存在dataset文件夹下a文件夹里的1.jpg小狗图片 二、读取测试图片&#xff0c;重新设置模型所规定的大小(32,32)&#xff0c;并转为tens…

二分法变种小结(leetcode 34、leetcode33、leetcode 81、leetcode 153、leetcode 74)

目录二分法细节1、leetcode 34 在排序数组中查找元素的第一个和最后一个位置2、不完全有序下的二分查找(leetcode33. 搜索旋转排序数组)3、含重复元素的不完全有序下的二分查找(81. 搜索旋转排序数组 II)3、不完全有序下的找最小元素(153. 寻找旋转排序数组中的最小值)4、二维矩…

ID3D11DeviceContext::Dispatch与numthread笔记

假定——[numthreads(TX, TY, TZ)] // 线程组尺寸。既线程组内有多少个线程。Dispatch(GX, GY, GZ); // 线程组的数量。既有多少个线程组。 那么——SV_GroupThreadID{iTX, iTY, iTZ} // 【线程组内的】线程3D编号SV_GroupID{iGX, iGY, iGZ} // 线程组的3D编号SV_DispatchT…

kotlin 查找id_Kotlin程序查找Square区域

kotlin 查找idFormula to find area of Square: area side*side 查找Square面积的公式&#xff1a; area side * side Given the value of side, we have to find the area of Square. 给定side的值&#xff0c;我们必须找到Square的面积。 Example: 例&#xff1a; Input…

小米手环6解决天气未同步问题

最近我发现了我的米6手环天气不同步&#xff0c;打开Zepp Life刷新同步也不行&#xff0c;后来我找了一些网上的解决方法&#xff0c;尝试了一些也还不行&#xff0c;我这人喜欢瞎捣鼓&#xff0c;无意之间给整好了&#xff0c;后来我开始总结自己操作步骤&#xff0c;就在刚才…