题目来源:AcWing 2816. 判断子序列
一、题目描述
给定一个长度为 n 的整数序列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,an 以及一个长度为 m m m 的整数序列 b 1 , b 2 , … , b m b_1,b_2,…,b_m b1,b2,…,bm。
请你判断 a a a 序列是否为 b b b 序列的子序列。
子序列指序列的一部分项按原有次序排列而得的序列,例如序列 a 1 , a 3 , a 5 {a_1,a_3,a_5} a1,a3,a5 是序列 a 1 , a 2 , a 3 , a 4 , a 5 {a_1,a_2,a_3,a_4,a_5} a1,a2,a3,a4,a5 的一个子序列。
输入格式
第一行包含两个整数
n
,
m
n,m
n,m。
第二行包含 n n n 个整数,表示 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,an。
第三行包含 m m m 个整数,表示 b 1 , b 2 , … , b m b_1,b_2,…,b_m b1,b2,…,bm。
输出格式
如果
a
a
a 序列是
b
b
b 序列的子序列,输出一行 Yes
。
否则,输出 No
。
数据范围
1
≤
n
≤
m
≤
1
0
5
,
1≤n≤m≤10^5,
1≤n≤m≤105,
−
1
0
9
≤
a
i
,
b
i
≤
1
0
9
−10^9≤a_i,b_i≤10^9
−109≤ai,bi≤109
输入样例:
3 5
1 3 5
1 2 3 4 5
输出样例:
Yes
二、算法思路
指针 i i i 指向 a a a 序列,指针 j j j 指向 b b b 序列。对于 b b b 中的每一个数 b j b_j bj 与 a i a_i ai 是否相同。如果相同,让 i i i 后移一位;否则访问 j j j 的下一个位置。
单调性:随着 j j j 往右侧移动, i i i 一定沿着右侧方向移动。
当 i i i 到达 n n n 时,说明子序列成立。
三、代码
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N], n, m;
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]);
for (int j = 0, i = 0; j < m; j++)
{
if (b[j] == a[i]) i++;
if (i == n)
{
puts("Yes");
return 0;
}
}
puts("No");
return 0;
}