求解一个序列中出现次数最多的元素贪心算法_基础算法(七)双指针

本文介绍了如何使用双指针算法优化求解一个序列中出现次数最多的元素的问题,从O(n²)的时间复杂度降低到O(n)。通过分析[i, j]区间,动态调整指针i和j,确保区间内无重复元素,从而找到最长连续不重复子序列。" 80268017,7281106,MySQL多表查询详解,"['数据库', 'SQL', '数据操作', '数据库查询']
摘要由CSDN通过智能技术生成

人类的赞歌就是勇气的赞歌。

01

算法思想

对于某些遍历问题,如求一个最长连续不重复子序列,我们可以当然可以想到用一个双循环暴力求解,这导致时间复杂度是O(n²),有没有优化此类问题的解决办法呢?这就是今天介绍的双指针算法。

我们依旧以上述例子为例来讲述该算法。

若要求一个[L,R]区间内的最长连续不重复子序列,我们设定两个指针i,j,初始时i,j都指向L,若某时刻i,j位置如图所示:

f26123aa881a8b369b4c1c4c0e9a06c0.png

如果此时[j,i]区间内没有重复元素,那么当i向右移动一次后:

25cdb96871304fa159b780a764f19a6c.png

有两种情况:

①[j,i]内仍然没有重复元素,那么我们可以继续移动i去寻找最长不重复序列。

②若出现了重复元素,则重复元素一定是此时i所指的元素,那么我们可以移动j,直到[j,i]内无重复元素。

无论哪种情况,我们处理完后,可以保证[j,i]没有重复元素,这样我们维护的[j,i]区间又变成了一开始的样子,就可以继续处理,整个过程只需另设一个结果变量,及时更新最长序列即可。

这样一来,我们就可以将双重循环退化为一次循环,将O(n²)的时间复杂度降到了O(n)。

02

代码模板

//一般模板//基本套路就是一个循环里面嵌套一个判断for(int i=0,j=0;i//i,j初始化一定要要为0    {        while(check()) j++;  //若通过check()函数判断出某些条件                                         }                        //则移动j指针        //对于上面讲到的求最长连续不重复子序列的求解int a[maxn];int book[maxn]; //book数组判断当前区间有无重复元素int main(){    int n;    cin>>n;    for(int i=0;i"%d",&a[i]);    int ans=0; //ans存放结果长度    for(int i=0,j=0;i    {        book[a[i]]++;      //第i个元素出现次数+1        while(book[a[i]] > 1) book[a[j]]--,j++;  //若新进来的这个元素重复出现                                                 //移动j指针,直到不再重复        ans=max(ans,i-j+1);  //更新最后的最长区间    }    cout<}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值