题目1-最长连续不重复子序列
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。
数据范围
1≤n≤105
输入样例:
5
1 2 2 3 5
输出样例:
3
//算法思想:用一个长度为100000的数组b来记录每个数字出现的次数,若数据出现就加上1.
//利用双指针,i是先头兵,j在后面收尾,先头兵i每次都往前前进一部,j在后面找到与当前
//的i匹配的最佳的不重复的序列的长度。输出最长的那个。#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>using namespace std;const int N=100000;int a[N],b[N];int main(){int n;cin>>n;for(int i=0;i<n;i++) cin>>a[i];int res=0,j=0;for(int i=0;i<n;i++){b[a[i]]++; //遍历过的a[i]中的元素在b[i]中的计数加1.while(b[a[i]]>1){ //如果其中的某个元素出现的次数大于1,就要移动j。b[a[j]]--; //j移动之前要把用来计数的b数组减去一j++; //j向后移动一位} res=max(res,i-j+1);}cout<<res;return 0;
}
算法思想:用一个长度为100000的数组b来记录每个数字出现的次数,若数据出现就加上1.
利用双指针,i是先头兵,j在后面收尾,先头兵i每次都往前前进一部,j在后面找到与当前
的i匹配的最佳的不重复的序列的长度。输出最长的那个。
题目2 判断子序列
给定一个长度为 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
//算法思想;设置两个指针分别指向两个数组的起始的位置,如果所指向的两个元素相同,则两个指针向前移动一位;
//如果两个元组不同,则只移动b、数组上面的指针。终止条件是如果a上面的指针指向的是最后一个元素的后面,那
//么就输出yes,否则输出no#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>using namespace std;const int N=100010;int a[N],b[N];int main(){int n,m;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 i; //j是指向数组a的指针for(i=0;i<m;i++){ //i是指向数组b的指针if(a[j]==b[i]) j++;if(j==n) break; //当满足条件时,跳出循环。}//cout<<i;if(j==n) printf("Yes");else printf("No");return 0;
}
算法思想;设置两个指针分别指向两个数组的起始的位置,如果所指向的两个元素相同,则两个指针向前移动一位;如果两个元组不同,则只移动b、数组上面的指针。终止条件是如果a上面的指针指向的是最后一个元素的后面,那么就输出yes,否则输出no。
题目3 数组元素的目标和
给定两个升序排序的有序数组 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的指针向右移动;当相等时输出。
//此外,不用考虑有相同的值的情况,因为题目中交代了数据保证有唯一解。#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>using namespace std;typedef long long ll;const int N=100000;
ll a[N],b[N];int main(){int n,m,x;cin>>n>>m>>x;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<m;i++) cin>>b[i];int j=0,i=n-1; //i指向数组a的最右端,j指向数组b中的最左端。while(1){ll tmp;tmp=a[i]+b[j];if(tmp>x) i--;//如果当前两个数的和比x大,i左移if(tmp<x) j++;//如果当前两个数的和比x小,j右移if(tmp==x) break;}cout<<i<<" "<<j;return 0;
}
算法思想:由于两个数组都是升序排列,所以可以利用双指针,其中一个指针指向数组A的最右端,另一个指针指向数组B的最左端,分别向左和向右移动。当当前指针指向的两个数的和大于目标值时,指向A的指针向左移动;当当前指针指向的两个数的和小于目标值时,指向B的指针向右移动;当相等时输出。此外,不用考虑有相同的值的情况,因为题目中交代了数据保证有唯一解。。