双指针【算法推导、背模板】——最长连续不重复子序列

news2024/9/20 14:27:36

799. 最长连续不重复子序列 - AcWing题库

通常情况双指针就是需要将O(N^2^),利用某些单调性质实现O(N)

通用代码模板

for(int i = 0 , j = 0; i < n ; i ++){
	while(j < i && check(i , j ) ) j ++;

	// 需要处理的逻辑
}

check判断是否构成

算法推导

题目中要求我们求

  • 最长的
  • 连续的
  • 不重复子序列

问题一:为什么能想到使用双指针算法?

双指针算法适用于多种场景,其中之一就是在一个序列中寻找一个连续的空间

在本题中,我们可以使用指针i遍历整个序列,使用另一个指针j维护以i为右端点——最长的不重复的子序列。

既然知道这题我们需要使用 双指针算法 寻找一个连续子序列,所以我们就可以带入模板

确定判断条件

带入模板后,我们需要确定在什么样的情况下,j++——也就是想清楚,check函数的逻辑

我们重新审题,发现题目一共有三个条件:最长连续不重复

使用双指针算法一定能让其连续,最长也可以通过设置比较res 和 (i到j的距离)得到最大值

所以这里的check函数的逻辑就是得到一个 不重复 的子序列!

问题二:如何判断该值是否在数组中出现过一次,是否重复?

这里我们想到的就是使用hash表进行判断,也就是在直接以输入的值作为key,每次遇到一次,对应的下标就+1

翻译成代码就是

s[ a[i] ] ++;

所以后续若我们需要判断是否重复过,只需要判断对应的a[i]是否大于1

我们来对输入样例数据1 2 2 3 5 来模拟一遍。

开始时,指针i和指针j同时指向第一个元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T8qdJiHq-1682000034349)(assets/image-20230420214905-8d8drb6.png)]

对应数组S的变化情况
> [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c0dh4rp2-1682000034351)(assets/image-20230420215112-jj5ulqn.png)]

判断当前s[a[i] ] = 1,不大于1

指针i指向下一个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoVB0YtZ-1682000034351)(assets/image-20230420215140-u5kbdcq.png)]

对应数组S的变化情况
> [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ib62nvXE-1682000034351)(assets/image-20230420215159-qax3plm.png)]

判断当前s[a[i] ] = 1,不大于1

i继续向后走

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cO2Y2Waz-1682000034352)(assets/image-20230420215301-ygedlzp.png)]

对应数组S的变化情况
在这里插入图片描述

判断当前s[a[i] ] = 2,大于1

所以此时需要将j++,对应记录的数组S就需要–了,因为子序列缩减了

因为数组S表示对应a[i]出现的次数

引申一下,就可以得到子序列的长度(因为子序列在遇到重复元素时是需要缩减的!)

指针J指向下标为1的位置,对应a[i] = 1的值减小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P9miG1yI-1682000034352)(assets/image-20230420215849-vuyo5n3.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bN7qppsL-1682000034352)(assets/image-20230420215858-zax2f3t.png)]

j继续向后走,对应值继续缩减

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJNozzPF-1682000034353)(assets/image-20230420220429-qwgk3dz.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4FlOcEs-1682000034353)(assets/image-20230420220436-tdzcy07.png)]

此时对应的数组S的值就不再>1,退出循环

此后就一直执行该判断,最后得到的结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HDLMqpnU-1682000034353)(assets/image-20230420220620-bd065s4.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kochIeyq-1682000034354)(assets/image-20230420220625-xw1eyut.png)]

所以最后得到的最长子序列长度就是3了,对应计算就呼之欲出了res = max(res , i - j + 1)

表示当前res 和 i和j之间的距离的最大值

问题三:为什么这里要用循环进行判断,而不是直接使用if,然后将j = i ,不是更好吗?

第一点:我们是使用的是双指针算法,算法模板中就是while循环

第二点:我们需要一个一个的消除值,因为我们的区间在不断缩减。如果我们直接将j = i,其中a[i]值前面的S数组的值就不会被清空,在后续遇到时,可能非法触发!!!

例如这个例子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SGEqXiKz-1682000034354)(assets/image-20230420221048-rww8psh.png)]

这里找到的最长子序列是[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yFdGylDl-1682000034354)(assets/image-20230420221128-adyso8o.png)]

但是实际序列是[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-55hReJPG-1682000034354)(assets/image-20230420221141-t7e2aw3.png)]

因为这里39都没有被清空,所以再一次遇到对应的s [ a[i] ]的值就会大于1,修改j的值

第三点:一般情况我们也是采用循环而不是判断,因为可能出现不同的情况,特别是对于这种前面的状态会影响后面的状态

解答代码

#include<iostream>

using namespace std;

const int N = 1e5+10;

int n , a[N] , s[N];

int main(){
    cin >> n;
  
    for(int i = 0 ; i < n ; i ++){
        cin >> a[i];
    }
  
    int res = 0;
  
    for(int i = 0 , j = 0 ; i < n ; i ++){
        s[a[i]] ++;
      
        while(s[a[i]] > 1){
            s[a[j]]--;
            j ++;
        }
      
        res = max(res , i - j + 1);
      
    }
    cout << res;
  
  
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/441135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM总结(持续更新中)

引言 当前LLM模型火出天际&#xff0c;但是做事还是需要脚踏实地。此文只是日常学习LLM&#xff0c;顺手整理所得。本篇博文更多侧重对话、问答类LLM上&#xff0c;其他方向&#xff08;代码生成&#xff09;这里暂不涉及&#xff0c;可以去看综述来了解。 之前LLM模型梳理 …

微服务---RabbitMQ与SpringAMQP基本使用

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&am…

OpenCV实例(四)手写数字识别

OpenCV实例&#xff08;四&#xff09;手写数字识别 1.基本原理2.实现步骤2.1数据准备2.2计算匹配值2.3获取最佳匹配值及对应模板2.4获取最佳匹配模板对应的数字2.5输出识别结果 3.代码实例 作者&#xff1a;Xiou 1.基本原理 使用模板匹配的方式实现手写数字识别&#xff0c;…

2023/4/20总结

项目 网上关于listview的资料太少了&#xff0c;在网上的那些资料里面&#xff0c;了解到以下这些。 如果希望listview后期能更改或者更新&#xff0c;那么需要使用到 ObservableList 它可以观察到&#xff0c;listview的改动。 需要特别注意一点的是&#xff1a;写俩者的…

如何发布自己的 npm 包?

一. 准备工作 1. 注册 npm 账号 还没有 npm 账号&#xff1f;去官网注册&#xff1a; https://www.npmjs.com/ 需要记住用户名、密码、邮箱 2. 查看本地 npm 镜像&#xff0c;如果不是默认的&#xff0c;需要改回来 npm config get registry重置镜像路径 npm config set r…

vulstack ATTCK(三)靶场

0x00环境搭建 两种形式 1.添加vmare2网卡&#xff0c;修改vmare2网卡的地址为192.168.93.0网段&#xff0c;注意不要在连接到主机适配器上打勾&#xff0c;这样会使本机也可以访问此电脑&#xff0c;5台机器都换成vmare2即可&#xff0c;第一台出网的centos在添加另一张nat网卡…

Docker容器---数据卷 数据容器

Docker容器---数据卷 数据容器 一、数据卷概述1、数据卷2、数据卷原理3、数据卷作用 二、数据卷容器1、数据卷容器作用2、创建数据卷容器 三、容器互联1、创建并运行源容器取名web12、创建并运行接收容器取名web2 一、数据卷概述 管理 Docker 容器中数据主要有两种方式&#x…

社科院与杜兰大学中外合作办学金融管理硕士项目——比起过往,前路更值得期待

当结束一天工作陷入沉思时&#xff0c;你有没有特别遗憾的事情呢&#xff0c;人生有太多的不确定性&#xff0c;比起过往&#xff0c;未知的人生更值得我们期待。与其懊恼没完成的遗憾&#xff0c;不如珍惜当下&#xff0c;努力创造未来。人生没有太晚的开始&#xff0c;在职读…

frp内网穿透——以连接到校园内网的服务器为例

有时候想摸鱼不去实验室&#xff0c;在宿舍就直接连接到实验室的GPU服务器。奈何服务器在校园网内部&#xff0c;外网无法直接直接访问。此时需要手动搭一个跳板机&#xff0c;来连接到内网的GPU服务器&#xff0c;这一过程怎么做到呢&#xff1f;我们可以使用frp内网穿透工具&…

Seata:连接数据与应用

作者&#xff1a;季敏&#xff08;清铭&#xff09;Seata 开源社区创始人&#xff0c;分布式事务团队负责人。 本文主要介绍分布式事务从内部到商业化和开源的演进历程&#xff0c;Seata 社区当前进展和未来规划。 Seata 是一款开源的分布式事务解决方案&#xff0c;旨在为现…

Java基础(十八):java比较器、系统相关类、数学相关类

Java基础系列文章 Java基础(一)&#xff1a;语言概述 Java基础(二)&#xff1a;原码、反码、补码及进制之间的运算 Java基础(三)&#xff1a;数据类型与进制 Java基础(四)&#xff1a;逻辑运算符和位运算符 Java基础(五)&#xff1a;流程控制语句 Java基础(六)&#xff1…

JavaScript黑科技:隐秘执行

JavaScript黑科技&#xff1a;隐秘执行 如果能使网页中的JavaScript代码隐密的加载、隐密的执行&#xff0c;那对于保护JavaScript代码来说是很有利的。 本文将探索、演示一种隐秘执行JavaScript代码的技术。 源码如下&#xff1a; <html> <script>window.onlo…

Prometheus+node_exporter+Grafana+夜莺 监控部署

一、安装Prometheus 1.1 部署并配置Prometheus #主机基础配置 [rootnode4~]# systemctl stop firewalld && systemctl disable firewalld [rootnode4~]# sed -i s/enforcing/disabled/g /etc/selinux/config && setenforce 0#上传prometheus安装包并解压 [r…

8、ThingsBoard使用docker compose集群部署的问题以及如何解决问题

1、问题回顾 接着上一节继续讲解,上一节我们把整个服务全部都运行起来了,但是访问页面报错,最后查看的问题是前端的容易里面报错: 然后执行脚本删除所有的容器 2、问题分析 当遇到这个问题的时候,我当时真的不知道如何去解决,然后我又尝试使用官方的镜像来部署,发现官…

P75分层解耦-IOCDI详解

一、分层解耦-三层架构 Dao层&#xff1a;数据访问 1、接口 package com.itheima.service;import com.itheima.pojo.Emp;import java.util.List;/*** Description:* date: 2023/4/19 21:47** since JDK 11*/ public interface EmpService { // 获取员工列表数据public List&l…

RabbitMQ·入门·壹

文章目录 1 MQ思想1.1 相关概念&#xff1a;同步、异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.2 MQ思想概述1.2.1 1 MQ思想 1.1 相关概念&#xff1a;同步、异步通讯 通讯方式举例优势劣势同步通讯就像打电话&#xff0c;需要实时响应。打电话可以立即得到响应。不能跟多人同时…

垃圾回收相关算法

标记阶段的算法 垃圾标记阶段&#xff1a;对象存货判断 在堆里存放着几乎所有的Java对象实例&#xff0c;在GC执行垃圾回收之前&#xff0c;首先需要区分出内存中哪些是存活对象&#xff0c;哪些是己经死亡的对象。只有被标记为己经死亡的对象&#xff0c;GC才会在执行垃圾回…

AutoGPT 环境搭建教程

文章目录 前言一、注册OpenAI和Pinecone的账号&#xff0c;并获取key二、下载Git和Python3&#xff08;自己网上搜&#xff0c;无脑安装&#xff09;![在这里插入图片描述](https://img-blog.csdnimg.cn/95bafd5ebe9d468cbceeacbfc0cb939b.png)三、进入GitHub&#xff0c;安装A…

Flowable从入门到源码分析

什么是工作流&#xff1f; 工作流&#xff0c;是把业务之间的各个步骤以及规则进行抽象和概括性的描述。使用特定的语言为业务流程建模&#xff0c;让其运行在计算机上&#xff0c;并让计算机进行计算和推动。 工作流解决的痛点在于&#xff0c;解除业务宏观流程和微观逻辑的…

【Linux】基础IO,详解系统文件IO

目录 C语言文件操作简单回顾 C语言相关文件接口汇总 默认打开的三个流 系统文件I/O open open的第一个参数 open的第二个参数 open的第三个参数 open的返回值 close write read 文件描述符 什么是文件描述符 文件描述符分配规则 重定向 重定向的本质 输出重定…