c++算法学习笔记 (9) 双指针

简介: c++算法学习笔记 (9) 双指针

1.最长连续不重复子序列

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

输入格式

第一行包含整数 n。

第二行包含 n 个整数(均在 0∼10^5 范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。

数据范围

1≤n≤10^5

输入样例:
5
1 2 2 3 5


输出样例:
3


34b61b71a86a487ba80fd68efb2ce089.jpg

(i作为终点枚举,j作为起点,在i固定时往右遍历到i)

#include <iostream>
#include <string.h>
using namespace std;
const int N = 100010;
int n;
int a[N];
int s[N]; // i到j每个数出现的次数
 
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]]++;//每次i往后走一个
        while (j <= i && s[a[i]] > 1)
        {
            s[a[j]]--;
            j++;
        }
        res = max(res, i - j + 1);
    }
    cout << res;
}


这里直接用数组s[N]存每个数的次数(因为数据比较小)。

若数据比较大,可以用map<int,int>存储数值及其次数。

请参考下面的例题:

https://developer.aliyun.com/article/1517795

2. 数组元素的目标和

给定两个升序排序有序数组 A 和 B,以及一个目标值 x。

数组下标从 00 开始。

请你求出满足 A[i]+B[j]=x 的数对 (i,j)。

数据保证有唯一解。

输入格式

第一行包含三个整数 n,m,x,分别表示 A 的长度,B 的长度以及目标值 x。

第二行包含 n 个整数,表示数组 A。

第三行包含 m 个整数,表示数组 B。

输出格式

共一行,包含两个整数 i 和 j。

数据范围

数组长度不超过 10^5。

同一数组内元素各不相同。

1≤数组元素≤10^9

输入样例:
4 5 6
1 2 4 7
3 4 6 8 9


输出样例:
1 


代码1:暴力(超时了)

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, m, x;
int a[N], b[N];
int main()
{
    cin >> n >> m >> x;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < m; i++)
        cin >> b[i];
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (a[i] + b[j] == x)
            {
                cout << i << " " << j;
                return 0;
            }
        }
    }
}


代码2:

思路:此题的AB数组都是升序,满足单调性,所以用双指针

#include <iostream>
using namespace std;
const int N = 100005;
int n, m, x;
int a[N], b[N];
int main()
{
    scanf("%d %d %d", &n, &m, &x);
    for (int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    for (int i = 0; i < m; i++)
        scanf("%d", &b[i]);
    for (int i = 0, j = m - 1; i < n; i++)
    { // i从开始,j从m-1开始,因为AB都为升序,所以Ai增大后Bi必然要减小(从两边向中间逼近答案)
        while (j >= 0 && a[i] + b[j] > x)
            // 找a[i] + b[j] > x&&j靠左的位置
            j--;
        if (a[i] + b[j] == x)
        {
            cout << i << " " << j;
            break;
        }
    }
    return 0;
}


3. 判断子序列

给定一个长度为 n 的整数序列 a1,a2,…,an 以及一个长度为 m 的整数序列 b1,b2,…,bm。

请你判断 a 序列是否为 b 序列的子序列。

子序列指序列的一部分项按原有次序排列而得的序列,例如序列 {a1,a3,a5} 是序列 {a1,a2,a3,a4,a5} 的一个子序列。

输入格式

第一行包含两个整数 n,m。

第二行包含 n 个整数,表示 a1,a2,…,an。

第三行包含 m 个整数,表示 b1,b2,…,bm。

输出格式

如果 a 序列是 b 序列的子序列,输出一行 Yes

否则,输出 No

数据范围

1≤n≤m≤10^5,

−10^9≤ai,bi≤10^9

输入样例:
3 5
1 3 5
1 2 3 4 5


输出样例:
Yes


#include <iostream>
using namespace std;
const int N = 100005;
int n, m;
int a[N], b[N];
int main()
{
    int n;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < m; i++)
        cin >> b[i];
    int j = 0;
    int num = 0;
    for (int i = 0; i < n; i++)
    {
        while (j < m && a[i] != b[j])
        {
            j++;
        }
        if (a[i] == b[j] && i < n && j < m)
        // 这里加上边界条件,否则j>=m后b[j]=0也会与a[i]作比较,若a[i]此时为0,就会有错误
        {
            num++;
            j++;
        }
    }
    if (num == n)
    {
        cout << "Yes";
    }
    else
    {
        cout << "No";
    }
    return 0;
}


相关文章
|
2天前
|
算法 数据处理 C++
C++一分钟之-迭代器与算法
【6月更文挑战第21天】C++ STL的迭代器统一了容器元素访问,分为多种类型,如输入、输出、前向、双向和随机访问。迭代器使用时需留意失效和类型匹配。STL算法如查找、排序、复制要求特定类型的迭代器,注意容器兼容性和返回值处理。适配器和算法组合增强灵活性,但过度使用可能降低代码可读性。掌握迭代器和算法能提升编程效率和代码质量。
21 3
|
6天前
|
算法 前端开发 Linux
【常用技巧】C++ STL容器操作:6种常用场景算法
STL在Linux C++中使用的非常普遍,掌握并合适的使用各种容器至关重要!
33 10
|
4天前
|
存储 算法 安全
C++一分钟之-数组与指针基础
【6月更文挑战第19天】在C++中,数组和指针是核心概念,数组是连续内存存储相同类型的数据,而指针是存储内存地址的变量。数组名等同于指向其首元素的常量指针。常见问题包括数组越界、尝试改变固定大小数组、不正确的指针算术以及忘记释放动态内存。使用动态分配和智能指针可避免这些问题。示例代码展示了安全访问和管理内存的方法,强调了实践的重要性。
20 3
|
8天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
8天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
8天前
|
存储 算法 C++
【数据结构与算法】:带你手搓顺序表(C/C++篇)
【数据结构与算法】:带你手搓顺序表(C/C++篇)
|
8天前
|
编译器 Linux C++
C++智能指针
**C++智能指针是RAII技术的体现,用于自动管理动态内存,防止内存泄漏。主要有三种类型:已废弃的std::auto_ptr、不可复制的std::unique_ptr和可共享的std::shared_ptr。std::unique_ptr通过禁止拷贝和赋值确保唯一所有权,而std::shared_ptr使用引用计数来协调多个指针对同一资源的共享。在C++17中,std::auto_ptr因设计缺陷被移除。**
|
3天前
|
机器学习/深度学习 算法 数据可视化
m基于PSO-LSTM粒子群优化长短记忆网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,应用PSO优化的LSTM模型提升了电力负荷预测效果。优化前预测波动大,优化后预测更稳定。PSO借鉴群体智能,寻找LSTM超参数(如学习率、隐藏层大小)的最优组合,以最小化误差。LSTM通过门控机制处理序列数据。代码显示了模型训练、预测及误差可视化过程。经过优化,模型性能得到改善。
18 6
|
1天前
|
缓存 算法
基于机会网络编码(COPE)的卫星网络路由算法matlab仿真
**摘要:** 该程序实现了一个基于机会网络编码(COPE)的卫星网络路由算法,旨在提升无线网络的传输效率和吞吐量。在MATLAB2022a中测试,结果显示了不同数据流个数下的网络吞吐量。算法通过Dijkstra函数寻找路径,计算编码机会(Nab和Nx),并根据编码机会减少传输次数。当有编码机会时,中间节点执行编码和解码操作,优化传输路径。结果以图表形式展示,显示数据流与吞吐量的关系,并保存为`R0.mat`。COPE算法预测和利用编码机会,适应卫星网络的动态特性,提高数据传输的可靠性和效率。
|
3天前
|
算法 调度
基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图
**摘要:** 实现变异混合蛙跳算法的MATLAB2022a版车间调度优化程序,支持动态调整工件和机器数,输出甘特图。核心算法结合SFLA与变异策略,解决Job-Shop Scheduling Problem,最小化总完成时间。SFLA模拟蛙群行为,分组进行局部搜索和全局信息交换。变异策略增强全局探索,避免局部最优。程序初始化随机解,按规则更新,经多次迭代和信息交换后终止。