当前位置:网站首页>最长连续不重复子序列 双指针
最长连续不重复子序列 双指针
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;
}
边栏推荐
猜你喜欢
【LeetCode】求和
Hash table problem solving method
【plang1.4.3】语言新特性:集合
振芯科技GM8285C:功能TTL转LVDS芯片简介
分割回文串 DP+回溯 (LeetCode-131)
【面试必看】链表的常见笔试题
Process (below): process control, termination, waiting, replacement
Arduino lights up nixie tubes
剑指Offer 35.复杂链表的复制
Process (present) : custom shell command line interpreter
随机推荐
R语言 —— 多元线性回归
剑指Offer 47.礼物的最大值 动态规划
【面试必看】链表的常见笔试题
开源代码交叉编译操作流程及遇到的问题解决(lightdm)
STM32 CAN 介绍以及相关配置
剑指Offer 31.栈的压入、弹出
改变文件的扩展名
Mac安装MySQL详细教程
Lightly:新一代的C语言IDE
USB HUB USB集线器电路设计
STM32F4 CAN 配置注意的细节问题
【详解】线程池及其自定义线程池的实现
install 命令
本地数据库 sqlite3 编译和使用
C语言教程 - 制作单位转换器
引擎开发日志:场景编辑器开发难点
DMA相应外设映射
哈希表解题方法
【LeetCode】链表相加 进位
回溯法 & 分支限界 - 2