0
点赞
收藏
分享

微信扫一扫

半导体自动化专用风机风棒的特点

书写经典 2023-07-13 阅读 55

(一)双指针算法的分类

(1)分别在两个数组上

图示如下:

(2)在一个数组之上

图示如下:

(二)双指针算法的模板

for(int i=0;i<n;i++){
    while(j<i && check(i,j)) j++;
    //每到题目的具体逻辑
}

(三)核心算法思想

//核心思想
for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        O(n^2);
}
}
//可以将上面的朴素算法优化到O(n)上来

 举例:

举例1:

输入

abc  bcd ekf

输出:

abc

bcd

ekf

例子2:

题目:最长连续不重复子序列

给定一个长度为 n

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

输入格式

第一行包含整数 n

第二行包含 n

个整数(均在 0∼105

范围内),表示整数序列。

输出格式

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

数据范围

1≤n≤105

输入样例:

5
1 2 2 3 5

输出样例:

3

 

代码

#include<iostream>
using namespace std;
const int maxn = 101000;
int a[maxn],s[maxn];//开辟两个数组a、s,a是用来保存原始的序列,s是是用来保存各个元素重复的次数

int main(){
    int n;
    int res = 0;//保存结果
    scanf("%d",&n);
    for(int i = 0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int i = 0,j=0;i<n;i++) {
        s[a[i]]++;
        while(s[a[i]]>1){//当遇到i位置的元素重复时
            s[a[j]] --;//使该元素减一
            j++;//并且使另一个指针进行右移
        }
        res = max(res,i-j+1);//返回最大的值
    }
    cout<<res<<endl;
    return 0;
}

 例子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

(双指针) O(n)

i从 0开始 从前往后遍历
j从 m - 1开始 从后向前遍历

和纯暴力的O(n2)

算法的区别就在于

    j指针不会回退


C++ 代码

#include<iostream>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn],b[maxn];
int m,n,x;
int main(){
    scanf("%d%d%d",&m,&n,&x);
    for(int i = 0;i < m;i++) scanf("%d",&a[i]);
    for(int i = 0;i < n;i++) scanf("%d",&b[i]);
    for(int i = 0,j=n-1;i < n;i++){
        while(j >= 0 && a[i] + b[j] > x){
            j--;
        }
        if(j >= 0 && a[i] + b[j] == x ){
            
            printf("%d %d\n",i,j);
            break;
        }
        
    }
    return 0;
}

例子4

题目

 

//暴力求解
/*
#include<iostream>
using namespace std;
const int maxn = 1e6 + 10;
int a[maxn],b[maxn];

int main(){
    int m,n;
    int res = 0,p = -1;
    scanf("%d%d",&m,&n);
    for(int  i = 0;i < m;i++) scanf("%d",&a[i]);
    for(int j = 0;j < n;j++) scanf("%d",&b[j]);
    for(int i = 0;i < m;i++){
        for(int j =0;j < n;j++){
            if(a[i] == b[j] && j > p){
                res++;
                p = j;
                break;
            }
        }
    }
    if(res == m) cout<<"Yes";
    else cout<<"No"<<endl;
}
*/

//利用双指针算法进行求解

#include <iostream>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn],b[maxn];

int main(){
    int n,m;
    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) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
}

举报

相关推荐

0 条评论