2022-11-05 Acwing每日一题

本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!

今天来复习双指针。双指针总是会利用数据的单调性等进行优化,通常的做法是先思考一边暴力的解法,然后利用数据的某种规律或特性使用双指针进行优化。

数组元素的目标和

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

数组下标从 0 开始。

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

数据保证有唯一解

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

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

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

输出格式
共一行,包含两个整数 i 和 j。

数据范围
数组长度不超过 105。
同一数组内元素各不相同。
1≤数组元素≤109
输入样例:
4 5 6
1 2 4 7
3 4 6 8 9
输出样例:
1 1

算法原理

先思考暴力的解法,一眼就可以看出来是双重循环遍历暴力求解。然后想想其数据特征是什么,我们发现题目所给数据一定具有唯一解,但还不够,最重要的特点是他们都是单调上升序列。可以发现在暴力求解时我们总会遍历A,B,对于A中的一个元素与B中所有元素的组合都不满足结果的情况没有处理,因此我们可以使用双指针,其中一个指向A数组的头,一个指向B数组的尾,由于其具有单调上升性,因此,如果A数组中的元素与B数组都不适合,就可以直接跳到下一个元素。

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    int n,m,x;
    cin >> n >> m >> x;
    int A[n+10],B[m+10];
    for(int i=0; i< n ; ++i)cin >> A[i];
    for(int i=0; i<m ; ++i) cin >> B[i];
    for(int i=0,j=m-1; i < n ; ++i){
        while(A[i]+B[j]>x)  --j;    // 根据单调性让j不再回溯,套用for-while循环实现O(n)
        if(A[i]+B[j] == x){
            cout << i << ' ' << j << endl;
            break;
        }
    }
    return 0;
}

判断子序列

给定一个长度为 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 ≤ 105
−109 ≤ ai,bi ≤ 109
输入样例:
3 5
1 3 5
1 2 3 4 5
输出样例:
Yes

算法原理

没啥原理,有个关键条件要注意即子序列是按照原序列排列而得,即出现的先后顺序一致,剩下的就是分两种情况讨论即可,当n==m时,有一个不相等就为No,当n<m时,两个指针分别指向两个数组A,B,如果所致元素相同就++i,每回合都++j

代码实现

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010;

int n, m;
int a[N], b[N];

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    for (int i = 0; i < m; i ++ ) scanf("%d", &b[i]);

    int i = 0, j = 0;
    while(i < n && j < m){
	if(a[i] == b[j]) ++i;
	++j;
	}
    if (i == n) puts("Yes");
    else puts("No");
    return 0;
}

posted @ 2022-11-05 16:50  ZmQmZa  阅读(17)  评论(0编辑  收藏  举报