当前位置:网站首页>最长连续不重复子序列 双指针
最长连续不重复子序列 双指针
2022-08-02 03:33:00 【小艾菜菜菜】
题目描述
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。
数据范围
1≤n≤105
输入样例:
5
1 2 2 3 5
输出样例:
3
解题思路
对于这类题可以利用双指针算法思想来进行思考:
1.遍历数组a中的每一个元素a[i],对于每一个i,找到 j 使得双指针[j,i] 维护的是以a[i]结尾的最长连续不重复的子序列,长度为i - j + 1,将这个长度与r 的较大者更新给 r 。
2.对于每一个 i 如何确定 j 的位置: 由于[ i - j + 1] 是前一步得到的最长连续不重复的子序列,所以如果 [ i, j ] 中有重复元素,一定是 a[i] ,因此右移 j 直到 a[i] 不重复为止(由于[ j, i - 1] 已经是前一步的最优解,此时 j 只能右移以剔除重复元素a[ i ] ,不可能左移增加元素,因此 j 具有 “单调性 ” ,由此本体可以使用双指针来降低复杂度)。
3.用数组 s 记录子序列 a[j ~i ] 中元素出现的次数,遍历过程中对于每一个 i 有四步操作:
cin元素a[i]
将a[i]出现次数s[a[i]]加1
若a[i]重复则右移j(s[a[j]]要减1)
确定j及更新当前长度i - j + 1给r。
代码实现
# include <iostream>
using namespace std;
const int N = 100010;
int a[N], s[N];
int main()
{
int n, r = 0;
cin >> n;
for (int i = 0, j = 0; i < n; ++ i)
{
cin >> a[i];
++ s[a[i]];
while (s[a[i]] > 1) -- s[a[j++]]; // 先减次数后右移
//便与理解可以分开写
/* while (s[a[i]]>1) { s[a[j]] --; j ++; } */
r = max(r, i - j + 1) ;
}
cout << r;
return 0;
}
边栏推荐
猜你喜欢
随机推荐
USB HUB USB集线器电路设计
MAC安装Mysql超详细完整教程
path 修补文件命令
【LeetCode】链表相加 进位
【详解】优先级队列的底层实现
改变文件的扩展名
【plang 1.4.4】编写茶几玛丽脚本
剑指Offer 13.机器人的运动范围 深度优先遍历
Kinematics Analysis of Robot Arm
剑指Offer 33.二叉搜索树的后序遍历序列
2020 - AAAI - 图像修复 Image Inpainting论文导读 -《Region Normalization for Image Inpainting》
【详解】线程池及其自定义线程池的实现
HDMI转MIPI CSI东芝转换芯片-TC358743XBG/TC358749XBG
龙芯2K1000使用nfs挂载文件系统进行使用
剑指Offer 36.二叉搜索树与双向链表 中序遍历
IDEA2021.2安装与配置(持续更新)
使用pyqt弹出消息提示框
Basic IO (below): soft and hard links and dynamic and static libraries
简单的RC滤波电路
bluez5.50蓝牙文件传输