双指针 (C/C++)

news/2024/11/24 19:14:42/

1. 双指针

双指针算法的核心思想:将暴力解法的时间复杂度,通常是O(N*N),通过某种特殊的性质优化到O(N)。

做题思路:先想想暴力解法的思路,然后分析这道题的特殊性质,一般是单调性。然后得出双指针算法的思路。

双指针算法的模板:

for(int i = 0; i <n; i++)

{

        while(j < i && check(i, j))

                j++;

        //具体题目的解题思路

}、

1.1 例题

给定一个长度为 n 的整数序列,请找出最长的不包含重复数数字的最长子序列,输出它的长度。

输入格式

第一行包含整数 n 。

第二行包含 n 个整数(均在0 ~ 100000范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复数字的连续子序列的长度。

数据范围

1 <= n <= 100000

按照上面介绍的解题思路:我们先看看暴力解法怎么做的:两层for循环,外层循环在遍历数组时,对于外层循环遍历的每一个值,内层循环都会从该位置开始去遍历,通过检查区间内是否存在重复数字,更新结果。显然这种解法的事件复杂度为O(N*N)。伪代码如下:

for (int i = 0; i < n; i++)
{
    for (j = i + 1; j < n; j++)
    {
        if (!check(i, j))
            ret = max(ret, i - j + 1);
    }
}

其中n为数组的长度,check为检查区间 [ i, j ] 中的元素是否存在重复的数字,如果不存在更新结果,保存到ret中。

双指针:同样根据上面提供的解题思路,我们尝试从暴力解法中分析出单调性。嗯,双指针的左侧指针在整个查找过程中是单调的。怎么理解呢?

下面以一个具体的例子:1,2,2,3,5 来分析哈:

 现在我们已经知道了双指针的大致思路了,但是好像还没有弄清除单调性从何而来。对于本题单调性就是:在 i++ 向右找更大的满足要求的更长区间时,j不可能存在向前动 (j--) 的情况。即,本题中 j 具有单调性。

 弄清除了这些,我们只需要知到怎么判定一个区间中是否有重复元素就行了。我们可以初始化一个数组a,遍历原数组b, 得到的值假设为s,就让 a[s] + 1,代表这个数字出现了一次。注意当一个区间中没有重复元素时,i++,那么只有原数组中下标为 i 的 的值才会是重复的元素,因此我们只需要判断 a[b[i]] 的值是否是大于 1 即可。这就是模板中的 check 。另外本题中不要 i > j 这个条件,因为 i == j 时,区间 [j, i] 中就没有重复的元素了,i然后就会加一,即 j 是不会大于 i 的。

当区间内存在重复元素时,j++的同时要将 a[b[j]]--,少了一个数字嘛。

 现在可以写代码啦!

int main()
{const int N = 100000;//原数组int b[N];//统计数字出现次数的数组int a[N] = { 0 };//用于保存最大的区间长度int ret = 0;int j = 0;//读入数据int n;scanf("%d", &n);for (int i = 0; i < n; i++){scanf("%d", &b[i]);}//核心算法for (int i = 0; i < n; i++){a[b[i]]++;while (a[b[i]] > 1){//少一个数字,次数减一a[b[j]]--;j++;}//更新结果ret = ret > i - j + 1 ? ret : i - j + 1;}//打印结果printf("%d\n", ret);system("pause");return 0;
}

1.2 小试牛刀(来源:Acwing)


http://www.ppmy.cn/news/27281.html

相关文章

机器学习聚类分析建模方法大全

最近很多私信都在问机器学习的问题&#xff0c;感觉很多都是刚入门的新手&#xff0c;有些概念和问题也相对比较基础&#xff0c;空余时间里我在不断整理一些常用的基础算法模型&#xff0c;写成文章后面有需要的话可以直接阅读即可&#xff0c;有些问题可能直接就迎刃而解了吧…

国内知名插画培训机构有哪些,学习插画怎么选培训班

国内知名插画培训机构有哪些&#xff1f;给大家梳理了国内5家专业的插画师培训班&#xff0c;最新无大插画班排行榜&#xff0c;各有优势和特色&#xff01; 一&#xff1a;国内知名插画培训机构排名 1、轻微课&#xff08;五颗星&#xff09; 主打课程有日系插画、游戏原画…

初识MySQL下载与安装【快速掌握知识点】

目录 前言 MySQL版本 MySQL类型 MySQL官网有.zip和.msi两种安装形式&#xff1b; MySQL 下载 1、MySQL 属于 Oracle 旗下产品&#xff0c;进入Oracle官网下载 2、点击产品&#xff0c;找到MySQL 3、进入MySQL页面 4、点击Download&#xff08;下载&#xff09;&#x…

关于Kubernetes不兼容Docker

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/129153459 参考文献&#xff1a;https://www.cnblogs.com/1234roro/p/16892031.html 一、总结 总结起来就是一句话&#xff1a; k8s只是弃用了dockershim&#xff0c;并不是弃用了整个Docker&#xf…

基于SpringBoot的外卖项目(详细开发过程)

基于SpringBootMyBatisPlus的外卖项目1、软件开发整体介绍软件开发流程角色分工2、外卖项目介绍项目介绍产品展示后台系统管理移动端技术选型功能结构角色3、开发环境的搭建开发环境说明建库建表Maven项目搭建项目的目录结构pom.xmlapplication.ymlReggieApplication启动类配置…

whistle+SwitchyOmega配置代理解决白名单跨越

文章目录whistleSwitchyOmega配置代理什么是whistle什么是SwitchyOmega示例&#xff1a;作用为什么不直接使用SwitchyOmega代理whistleSwitchyOmega配置代理 什么是whistle whistle主要用于查看、修改HTTP、HTTPS、Websocket的请求、响应&#xff0c;也可以作为HTTP代理服务器…

ideal创建maven项目

前置工作本机安装mavenIdea 设置使用本机maven 工具Settings--->Maven开始创建maven项目创建maven项目&#xff0c;勾选通过模板创建&#xff0c;选择 maven-archetype-webapp 模板GroupId: 公司名倒序ArtifactId: 项目名设置本地maven仓库配置项目文件显示名&#xff0c;和…

C语言——柔性数组

目录0. 前言1. 思维导图2. 柔性数组的特点3. 柔性数组的使用4. 柔性数组的优势5. 结语0. 前言 柔性数组是在C99标准时引入&#xff1a; 结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫柔性数组成员。 代码示例&#xff1a; typedef struct flexible_arr {int a…