【算法系列总结之分组循环篇】

【算法系列总结之分组循环篇】

    • 分组循环
      • 1446.连续字符
      • 1869.哪种连续子字符串更长
      • 1957.删除字符使字符串变好
      • 2038.如果相邻两个颜色均相同则删除当前颜色
      • 1759.统计同质子字符串的数目
      • 2110.股票平滑下跌阶段的数目
      • 1578.使绳子变成彩色的最短时间
      • 1839.所有元音按顺序排布的最长子字符串
      • 2760.最长奇偶子数组
      • 2765.最长交替子序列
      • 228.汇总区间

分组循环

分组循环指的是将整个数组或者字符串分为很多片段,这些片段的判断处理逻辑是一样的。分组循环需要使用同向双指针,但是与滑动窗口不同的是,滑动窗口是收集左右区间内连续数组或者字符串,当不满足收集要求时移动右指针,而当满足后移动左指针,此时左指针移动到原来左指针的下一位,而分组循环是左指针移动到右指针下一位。

// 模板 l、r分别表示左右指针int l=0,r=0;while(r<n){// 每一次求新区间则重新赋值ll=r;// r表示最长连续区间最后一个while(r<n-1&&s[r]==s[r+1])r++;// 求完区间后收集结果res=max(r-l+1,res);// 并移动r到下一个r++;}

1446.连续字符

思路:分组循环,相当于把字符串分为多个连续相同字符片段,利用左右端点l、r求解最长连续相同字符片段长度。

class Solution {
public:int maxPower(string s) {int n=s.size();int l=0,r=0;int res=0;while(r<n){// 每一次求新区间则重新赋值ll=r;// r表示最长连续区间最后一个while(r<n-1&&s[r]==s[r+1])r++;// 求完区间后收集结果res=max(r-l+1,res);// 并移动r到下一个r++;}return res;}
};

1869.哪种连续子字符串更长

思路:分组循环,相当于把字符串分为多个连续1或者0字符片段,利用左右端点l、r和元素s[l]求解最长连续1或者0字符片段长度,再根据条件返回对应结果。

class Solution {
public:bool checkZeroOnes(string s) {// 分别记录最长1、最长0长度int num1=0,num0=0;int n=s.size();// 区间左右端点int l=0,r=0;while(r<n){// l表示每轮左区间l=r;// r表示当前符合条件区间右端点while(r<n-1&&s[r]==s[r+1])r++;// 收集0或者1长度if(s[l]=='0')num0=max(num0,r-l+1);elsenum1=max(num1,r-l+1);r++;}return num1>num0;}
};

1957.删除字符使字符串变好

思路:分组循环,相当于把字符串分为多个连续相同片段,利用左右端点l、r求解每一个连续相同片段长度,如果长度小于3则直接将该片段加入结果,反之则只加入两个字符即可。

class Solution {
public:string makeFancyString(string s) {string res;int n=s.size();int l=0,r=0;while(r<n){l=r;while(r<n-1&&s[r]==s[r+1])r++;if(r-l+1<3)res+=s.substr(l,r-l+1);else {// 加入两次res.push_back(s[l]);res.push_back(s[l]);}r++;}return res;}
};

2038.如果相邻两个颜色均相同则删除当前颜色

思路:分组循环,相当于把字符串分为多个连续A或者B字符片段,利用左右端点l、r和元素colors[l]求解最长连续A或者B字符片段可选择的次数,再根据条件返回对应结果。注意,最长连续A或者B字符片段可选择的次数为在保留左右两边字符的情况下中间所有剩余字符,即一旦长度大于等于3则为长度减去2,反之则为0,由于A是先手,故A必须严格大于B。

class Solution {
public:bool winnerOfGame(string colors) {int n=colors.size();// 转换为次数int numA=0,numB=0;int l=0,r=0;while(r<n){l=r;while(r<n-1&&colors[r]==colors[r+1])r++;// 一旦>=3 则可移动的为长度减去左右两边2if(colors[l]=='A')numA+=(r-l+1)>=3?(r-l+1)-2:0;elsenumB+=(r-l+1)>=3?(r-l+1)-2:0;r++;}return numA>numB;}
};

1759.统计同质子字符串的数目

思路:分组循环,相当于把字符串分为多个连续相同片段,利用左右端点l、r求解每一个连续相同片段长度,然后利用1、3、6、10、15…规律根据长度n求出方案数n*(n+1)/2,最后累计方案数即可。

class Solution {
public:const long long NUM=1e9+7;int countHomogenous(string s) {// 1 3 6 10 15 n*(n+1)/2int n=s.size();int l=0,r=0;// long long 避免精度不够long long res=0;while(r<n){l=r;while(r<n-1&&s[r]==s[r+1])r++;int len=r-l+1;// 注意取模res+=(long long)(len+1)*len/2;r++;}// 取模return res%NUM;}
};

2110.股票平滑下跌阶段的数目

思路:分组循环,相当于把数组分为多个连续公差为1的递减片段,利用左右端点l、r求解每一个连续公差为1的递减片段长度,然后利用1、3、6、10、15…规律根据长度n求出方案数n*(n+1)/2,最后累计方案数即可。

class Solution {
public:long long getDescentPeriods(vector<int>& prices) {int n=prices.size();int l=0,r=0;long long res=0;while(r<n){l=r;// 当前日比前一日股价少一while(r<n-1&&prices[r]==prices[r+1]+1)r++;long long len=r-l+1;res+=len*(len+1)/2;r++;}return res;}
};

1578.使绳子变成彩色的最短时间

思路:分组循环,相当于把绳子分为多个连续相同气球片段,利用左右端点l、r求解每一个连续相同气球片段,并对每个大于1的片段求解总时间和最大时间从而得到最小时间,对这些时间累加即可得到结果。

class Solution {
public:int minCost(string colors, vector<int>& neededTime) {int n=colors.size();int l=0,r=0;int res=0;while(r<n){l=r;while(r<n-1&&colors[r]==colors[r+1])r++;if(l!=r){int maxn=0;for(int i=l;i<=r;i++){maxn=max(neededTime[i],maxn);res+=neededTime[i];}res-=maxn;}r++;}return res;}
};

1839.所有元音按顺序排布的最长子字符串

思路:分组循环,相当于把字符串分为多个按照元音字母递增的至少含有所有元音字母各一个的字符串,与前面几题不同的是,该题需要在记录符合区间的同时,也使用uset来记录元音字母个数,从而便于后序收集结果条件各个元音字母至少一个的判断。

class Solution {
public:int longestBeautifulSubstring(string word) {int n=word.size();int l=0,r=0;int res=0;while(r<n){l=r;// 存储次数 保证各个字母至少出现一次unordered_set<int> uset;// 按照 a e i o u顺序while(r<n-1&&word[r+1]>=word[r]){uset.emplace(word[r]);r++;}// 加入最后一个 前几题都是只需r++ 不需额外处理uset.emplace(word[r]);// cout<<uset.size()<<endl;if(uset.size()==5)res=max(res,r-l+1);r++;}return res;}
};

2760.最长奇偶子数组

思路:分组循环,相当于把数组分为多个[l,r]区间,其中求出满足题目要求的长度最长的[l,r]区间。该题与上述题目不同的地方在于,该题中存在l、[l,r-1]、[l,r]三个判断,由于此处的差异就会导致在处理判断边界条件时可能会出现些许差异和错误。此处首先对于l不满足的情况进行特殊处理,由于已经处理过l,那么后续就是在l满足条件的情况下进行,此时将r加一,相当于比较r和r-1,而不是原先的r和r+1,那么相应的此处得到的r就是第一个不满足的,对应的长度变为r-l,同时也不需要继续对r++啦。(注意细节)

class Solution {
public:int longestAlternatingSubarray(vector<int>& nums, int threshold) {int n=nums.size();int l=0,r=0;int res=0;while(r<n){// 左区间都不满足情况直接下一个if(nums[r]%2!=0||nums[r]>threshold){// continue之前记得r++啊否则区间不动r++;continue;}// 此处才更新左区间l=r;// 左区间已经满足 此时r+1r+=1;// r是第一个不满足的 故此时长度为r-l 并且后续不需要r++while(r<n&&nums[r]<=threshold&&(nums[r]%2!=nums[r-1]%2))r++;res=max(res,r-l);}return res;}
};

2765.最长交替子序列

思路:分组循环,相当于把数组分为多个[l,r]区间,其中求出满足题目要求的长度最长的[l,r]区间。该题与2760不同的地方在于,该题所分得的区间可能重叠喔,比如2 3 4 3 4,其中2 3和3 4 3 4其重叠一个,但是其最多也只会重叠一个,故我们找到第一个不满足的r后回退1即可。建议在分组循环类别的题目中,遇到给区间[l,r]设置条件时先对首部条件进行不合法判断处理再继续喔!

class Solution {
public:int alternatingSubarray(vector<int>& nums) {int n=nums.size();int l=0,r=0;int res=-1;// 数组长度至少为2!!!while(r+1<n){// 排除s1!=s0+1的情况if(nums[r+1]-nums[r]!=1){r++;continue;}// 记录左端点l=r;r+=1; // 右端点加一 至少长度为2int m=1;// r是第一个不满足的while(r<n&&nums[r]-nums[r-1]==m){r++;m*=-1;}res=max(res,r-l);// 2 3 4 3 4 // 2 3和3 4 3 4重合一个 为什么能保证最多重复一个r-=1; // 所以r需要回退一个}return res;}
};

总结:灵老师的nums[i]==nums[i0+(i-i0)%2]也很灵性!!!

228.汇总区间

思路:分组循环,相当于把字符串分为多个连续公差为1的递增片段,利用左右端点l、r求解每一个连续公差为1的递增片段两端,并按照要求格式加入结果。

class Solution {
public:vector<string> summaryRanges(vector<int>& nums) {int n=nums.size();int r=0,l;string tmp;vector<string> res;// l 左端點 r右端點 同向雙指針while(r<n){l=r;while(r<n-1&&nums[r]+1==nums[r+1])r++;tmp=to_string(nums[l]);if(l<r)tmp+="->"+to_string(nums[r]);res.push_back(tmp);r++;}return res;}
};

有一说一,虽然现在力扣刷了四百多题,牛客刷了两百多题,包括前端和算法,但还是觉得遇到一些脑筋急转弯的简单或者中等题还是不会,对于一些题型也没有形成自己的解题思路逻辑,遇到困难题也是要看题解才行,除非自己刷过几次,感觉好挫败啊呜呜呜呜呜呜呜呜,要怎么办!!!

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

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

相关文章

自动驾驶——最优控制算法(LQR)工程化总结

时隔一年&#xff0c;从写下第一篇博文自动驾驶-LQR工程实现&#xff08;调研&#xff09;&#xff0c;到近段时间&#xff0c;真正在我们的控制器上运行最优控制算法&#xff08;LQR&#xff09;&#xff0c;一步一个脚印&#xff0c;从开始只是知道其“控制理论”的阶段、再到…

Diffusion Models for Image Restoration and Enhancement – A Comprehensive Survey

图像恢复与增强的扩散模型综述 论文链接&#xff1a;https://arxiv.org/abs/2308.09388 项目地址&#xff1a;https://github.com/lixinustc/Awesome-diffusion-model-for-image-processing/ Abstract 图像恢复(IR)一直是低水平视觉领域不可或缺的一项具有挑战性的任务&…

vue helloworld.vue 点击按钮弹出 dialog,并给dialog传值

1 DataAnalysisVue.Vue -->应该组件文件名和 name: 的名字一致 <template><div><el-dialog :title"dataAnalysisMsg" :visible.sync"dataAnalysisvalue" :before-close"handleClose"><span>{{ dataAnalysisMsg }}&l…

Oracle 19c 启动和关闭实例保存PDB状态

简介&#xff1a; 十年以上 MySQL Oracle DBA从业者&#xff0c;MySQL 5.7 OCP&#xff0c; 微信号: jinjushuke 当前有一个PDB 打开模式为READ WRITE [oracleDGMOGGM19C ~]$ sql sys192.168.3.107:1521/pdb1 as sysdba SQLcl: Release 19.1 Production on Wed Aug 23 10:19:…

excel中如果A列中某项有多条记录,针对A列中相同的项,将B列值进行相加合并统计

excel中如果A列中某项有多条记录&#xff0c;针对A列中相同的项&#xff0c;将B列值进行相加合并统计。注意&#xff1a;B列的数据类型要为数字 如&#xff1a; 实现方法&#xff1a; C1、D1中分别输入公式&#xff0c;然后下拉 IF(COUNTIF($A$1:A1,A1)1, A1,"") …

C++:构造方法(函数);拷贝(复制)构造函数:浅拷贝、深拷贝;析构函数。

1.构造方法(函数) 构造方法是一种特殊的成员方法&#xff0c;与其他成员方法不同: 构造方法的名字必须与类名相同&#xff1b; 无类型、可有参数、可重载 会自动生成&#xff0c;可自定义 一般形式:类名(形参)&#xff1b; 例: Stu(int age); 当用户没自定义构造方法时&…

光伏发电+boost+储能+双向dcdc+并网逆变器控制(低压用户型电能路由器仿真模型)【含个人笔记+建模参考】

MATALB代码链接&#xff1a;光伏发电boost十储能十双向dcdc十并网逆变器 个人笔记与建模参考请私信发送 包含Boost、Buck-boost双向DCDC、并网逆变器三大控制部分 boost电路应用mppt&#xff0c; 采用扰动观察法实现光能最大功率点跟踪 电流环的逆变器控制策略 双向dcdc储能系…

react导出、导入文件

导出文件&#xff1a; if (res) {let binaryData [];binaryData.push(res);let blobUrl ;blobUrl res;// let blobUrl window.URL.createObjectURL(new Blob(binaryData, { type: application / zip }));console.log(blobUrl);const eleLink document.createElement(a);el…

Windows商店引入SUSE Linux Enterprise Server和openSUSE Leap

在上个月的Build 2017开发者大会上&#xff0c;微软宣布将SUSE&#xff0c;Ubuntu和Fedora引入Windows 商店&#xff0c;反应出微软对开放源码社区的更多承诺。 该公司去年以铂金会员身份加入Linux基金会。现在&#xff0c;微软针对内测者的Windows商店已经开始提供 部分Linux发…

题解:ABC280C - Extra Character

题解&#xff1a;ABC280C - Extra Character 题目 链接&#xff1a;Atcoder。 链接&#xff1a;洛谷。 难度 算法难度&#xff1a;C。 思维难度&#xff1a;B。 调码难度&#xff1a;C。 综合评价&#xff1a;入门。 算法 模拟。 思路 依次遍历s、t的每一项&#x…

pbootcms系统安全防护设置大全

PbootCMS系统简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统&#xff0c;是一套高效、简洁、 强悍的可免费商用的PHP CMS源码&#xff0c;能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签&#xff0c;只要懂HTML就可快速开发企业网站…

ElasticSearch - 海量数据索引拆分的一些思考

文章目录 困难解决方案初始方案及存在的问题segment merge引入预排序 拆分方案设计考量点如何去除冗余数据按什么维度拆分&#xff0c;拆多少个最终的索引拆分模型演进历程整体迁移流程全量迁移流程流量回放比对验证异步转同步多索引联查优化效果 总结与思考参考 困难 索引数据…

hive表的全关联full join用法

背景&#xff1a;实际开发中需要用到全关联的用法&#xff0c;之前没遇到过&#xff0c;现在记录一下。需求是找到两张表的并集。 全关联的解释如下&#xff1b; 下面建两张表进行测试 test_a表的数据如下 test_b表的数据如下&#xff1b; 写第一个full join 的SQL进行查询…

rust工程

文章目录 CargomacOS配置rust环境vscode配置 目录结构Cargo.tomlcargo命令hello world 跟web交互WebAssembly 跟Android交互配置Android环境JNI例子NDK例子 Rust 是一种现代的、系统级的编程语言&#xff0c;它强调并发安全、内存安全和高性能。Rust 的设计目标是提供一种有着良…

Java中LinkList的基本介绍和细节讨论。双向链表的代码和LinkList的源码。LinkList和ArrayList的比较与选择。

LinkedList 是 Java 中的一个双向链表实现的类&#xff0c;它实现了 List 接口&#xff0c;同时也实现了 Deque 接口&#xff0c;因此可以用作列表、队列或双端队列。下面是关于 LinkedList 的基本介绍和细节讨论&#xff1a; 基本介绍&#xff1a; LinkedList 是一个双向链表…

keepalived+haproxy 搭建高可用高负载高性能rabbitmq集群

一、环境准备 1. 我这里准备了三台centos7 虚拟机 主机名主机地址软件node-01192.168.157.133rabbitmq、erlang、haproxy、keepalivednode-02192.168.157.134rabbitmq、erlang、haproxy、keepalivednode-03192.168.157.135rabbitmq、erlang 2. 关闭三台机器的防火墙 # 关闭…

合并两个链表

题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 比如以下例子&#xff1a; 题目接口&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListN…

SQL阶段性优化

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;MySQL、SQL优化、阶段性优化☀️每日 一言&#xff1a;我们要把懦弱扼杀在摇篮中。 一、前言 我们在做系统的过程中&#xff0c;难免会遇到页面查询速度慢&#xff0c;性能差的问题&#xff0c;…

mysql57、mysql80 目录结构 之 Windows

查看mysql 数据存储的位置 /bin&#xff1a;存储可执行文件&#xff0c;主要包含客户端和服务端启动程序&#xff0c;如mysql.exe、mysqld.exe等 /docs&#xff1a;存放一些文档 /include&#xff1a;用于放置一些头文件&#xff0c;如&#xff1a;mysql.h、mysqld_error.h 等 …

Promise.all和promise.race的应用场景举例

Promise.all( ).then( )适用于处理多个异步任务&#xff0c;且所有的异步任务都得到结果时的情况。 <template><div class"box"><el-button type"primary" plain click"clickFn">点开弹出框</el-button></div> &…