算法扩展第一次:收集雪花 【hash表,双指针,stl中的map】

算法详解

这道题需要新学的知识一个是双指针,一个是c++库中的unordered_map容器

双指针

双指针原先我写过很多这方面的题,但是这道题我一开始是低估了它的难度,而且压根没有想到要用双指针,属于是长见识了,这道题的双指针的作用是维护一个移动窗口,这个移动窗口中没有重复的元素就可以了,至于为啥需要维护这个窗口呢?原因如下:因为可以求出整个队列中出现了多少哥不同的数字。过程如下:

至于为啥可以求出多少个不同的数字,原因是因为我们维护的这个窗口它是没有重复的元素的,当窗口中有重复的元素的时候,我们记录此时的单个元素最大值res为R-L,然后我们的左指针就会向前移动,一直到窗口周中没有重复的元素为止。等到窗口中没有重复元素(相当于我们把重复元素已经放入了res中)右指针(R)继续往前走,直达这个窗口中又有重复元素,我们只需要res=max(res,R-L)即可,这样就可以求出最大的res了。还不懂的自己动手画一画就懂了。

算法题解

#include<iostream>
#include<algorithm>
#include<unordered_map>

using namespace std;

const int N = 100010;
unordered_map<int,int> cur;
//last[i]表示下标i的上一个相同元素的下标。
int Last[N]; 

int main()
{
    int n;
    cin>>n;
    int a;
//初始化Last
    for(int i=0;i<n;i++){
        cin>>a;
        //map.count(a)在容器中查找以 key 键的键值对的个数。
        if(!cur.count(a)) Last[i]=-1;
        else Last[i] = cur[a];
        cur[a] = i;
    }
//指针就是int类型
    int R=0,L=0,res=0;
//使用Last来判断窗口是否有重复的元素
//窗口是数组中下标R到L之间的区间
    while(R>=L&&R<n){
//当有重复元素就停止右指针的前进,然后更新最大窗口大小
    	while(R<n&&Last[R]<L) R++;
		res=max(R-L,res);
		L++;
	}
	cout<<res<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值