蜗牛旅游----最长不重复子串


describe

蜗牛在制定今天的旅游计划,有 n 个景点可选,它已经把这些景点按照顺路游览的顺序排

成一排了,每个地方有相应的景观,这里用一个整数表示。

蜗牛希望选取连续的一段景点,还要选出来的每一个景点的景观都不同,问它最多能选出

多少个景点进行旅游。


limit

timememory
1000ms524288K

输入格式

第一行,一个正整数 n(1≤n≤10 ^ 5)

第二行,包含 n 个正整数 ai (1≤ai≤10 ^ 6),第 i 个整数表示第 i 个景点的景观

输入样例

5
1 2 3 2 1

输出格式

输出一行,包含一个整数,表示蜗牛最多能选出的景点数

输出样例

3

解析

本题的原型为求一个字符串中最长的不重复子串,使用 滑动窗口 算法解决

将输入的5个数1 2 3 2 1保存到容器中

在vector容器上面维护一个滑动窗口set(推荐unordered_set);满足条件则窗口增大,不满足

则缩小,途中记录区间大小,输出最终结果3,本题也可用双指针来维护窗口,效率更高.

c++代码
#include <iostream>
using namespace std;

#include <set>
#include <vector>

//需要被访问的数据或字符串
vector<int> vect;
int temp;
int ans;

//窗口
set<int> uset;

int main(){
//保存输入数据
    int a;
    cin>>a;
    while(a--){
        cin>>temp;
        vect.push_back(temp);
    }

    vector<int>::iterator left=vect.begin();
    vector<int>::iterator right=vect.begin();
    vector<int>::iterator ed=vect.end();

//while跳出循环时,right==ed
    while(right!=ed){
    	//判断当前right指向是否满足,不满足则跳出循环,此时right指向不满足的地方
         while(!uset.count(*right)&&right!=ed){
            uset.insert(*right);
            right++;
        }
        
        //记录窗口大小
        temp=right-left;
        ans=max(ans , temp);

		//缩小窗口,退出循坏时,left指向不包含right的地方
        while(uset.count(*right)&&left<right){
            uset.erase(*left);
            left++;
        }
    }
   
    cout<<ans;
    return 0;
}


!

  1. 窗口是一个左闭右开的区间,即用right指针指向的地方是不满足条件的,流入到下一次外循环中,left则不断的缩小.左闭右开时,right-left 即可求出区间长. 即[1,2,3,4,5), 区间长为5-1=4;
  2. 对while()循坏的跳出条件需要熟悉,while(!uset.count(*right)&&right!=ed)
    当uset.count(*right)或right==ed时跳出本循环,此时right指向的是容器中已有的值,或者end().即1 2 3 2 1,right此时指向2.再如left指针,跳出循环时,即1 2 3 2 1,left此时指向3.
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值