HNUST 1608: 最长连续相异子序列长度(离散化加滑动窗口)

题目描述:

给出一个含有n个数的序列,求一段最长的连续子序列的长度且这个子序列中不存在相同的数;

输入:

题目由多组数据组成,不超过30组

每组数据由两行组成,第一行输入一个数n(0<n<=10^5)表示序列的长度;接下来一行是n个整数,每个数大于0且小于2^31;

输入以EOF结尾。

输出:

对于每组测试数据,输出一行表示最长连续相异子序列的长度;

题解:将大数据转化为小数据,便于用数组记录该数的出现次数,如果直接用map的话时间复杂度更大,注意map的查看也要时间且平均时间复杂度为O(log(N)),删除,查找,也一样。故用数组标记查看时间复杂度为O(1)。

做题的思路为:初始存下第一个数的位置(定为j),一直向前遍历,等到找到出现了两次的数的时候就可以找到一个连续相异序列,此时长度为i-j+1,再令j++,之后循环此操作即可。

​
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define endl '\n'
#define N 100005
using namespace std;
const ll inf=0x3f3f3f3f;
const double PI=acos(-1);
const int mod=32768;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
int a[N],k[N],b[N],n;
int solve()
{
    sort(a,a+n);
    int l = unique(a,a+n)-a;
    for(int i=0;i<n;i++)
    {
        k[i]=lower_bound(a,a+l,k[i])-a;
    }
    int ans=0;
    for(int i=0,j=0;i<n;i++)
    {
        b[k[i]]++;
        while(b[k[i]]>1)
        {
            --b[k[j++]];
        }
        ans=max(ans,i-j+1);
    }
    return ans;
}
int main()
{ios
    while(cin >>n)
    {
        for(int i=0;i<n;i++)
        {
            cin >>a[i];
            k[i]=a[i];
            b[i]=0;
        }
        cout <<solve()<<endl;
    }
    return 0;
}

​
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值