• Acwing双指针算法


    题目所属分类

    双指针算法 与leetcode描写的数组系列总结部分很像 都是双指针算法
    模板大抵如下:

    for (int i = 0, j = 0; i < n; i ++ )
    {
        while (j < i && check(i, j)) j ++ ;
    
        // 具体问题的逻辑
    }
    常见问题分类:
        (1) 对于一个序列,用两个指针维护一段区间
        (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    一、 799. 最长连续不重复子序列(模板题)

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

    输入格式
    第一行包含整数 n。

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

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

    数据范围
    1≤n≤105

    代码案例:输入:5
    1 2 2 3 5
    输出 3

    题解

    这是指向一个序列
    换做字符串的话 还是得需要哈希表 但是Java中的哈希表写起来保存的话没有数组这样省力

    import java.util.Scanner;
    public class Main{
        static int N = 100010;
        public static void main(String[] args){
            Scanner scan = new Scanner(System.in);
            int n = scan.nextInt();
            int[] a = new int[N];
            int[] h = new int[N];
            int res = 0 ;
            for(int i = 0; i < n ; i++){
                a[i] = scan.nextInt();
            }
            for(int i = 0 ,j = 0; i < n ; i++){
                h[a[i]]++;
                while(j< i &&h[a[i]] > 1){
                    h[a[j]]--;
                    j++;
                }
                res = Math.max(res,i - j + 1);
            }
           System.out.println(res);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    二、800. 数组元素的目标和

    给定两个升序排序的有序数组 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

    题解

    在这里插入图片描述
    最多只遍历了n+m个值,所以时间复杂度就n+m 双指针算法还是要考虑到单调性
    指向两个序列

    import java.util.Scanner;
    public class Main{
        static int N = 100010;
        public static void main(String[] args){
            Scanner scan = new Scanner(System.in);
            int n = scan.nextInt();
            int m = scan.nextInt();
            int x = scan.nextInt();
            int[] a  = new int[N];
            int[] b  = new int[N];
            int res = 0 ,ans  =0 ;
            for(int i = 0 ; i < n ; i++){
                a[i] = scan.nextInt();
            }
            for(int i = 0 ; i < m ; i++){
                b[i] = scan.nextInt();
            }
            for(int i = 0 , j = m-1 ; i < n ; i++){
                while(j >= 0 && b[j] + a[i] > x ){
                    j--;
                }
                if(j >= 0 && b[j] + a[i] == x) System.out.println(i +" "+ j);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    三、2816. 判断子序列

    给定一个长度为 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。
    在这里插入图片描述

    import java.util.Scanner;
    public class Main{
        static int N = 100010;
        public static void main(String[] args){
            Scanner scan = new Scanner(System.in);
            int n = scan.nextInt();
            int m = scan.nextInt();
            int[] a = new int[N];
            int[] b = new int[N];
            for(int i = 0 ; i< n ; i++){
                a[i] = scan.nextInt();
            }
            for(int i = 0 ; i< m ; i++){
                b[i] = scan.nextInt();
            }
            int i = 0 , j = 0 ;
             while(i < n&& j < m  ){
                 if(a[i] == b[j]) i++;
                 j++;
             }
             if(i == n )System.out.println("Yes");
             else System.out.println("No");
                
             
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    使用REDIS的INCREMENT方法生成自增主键,并发量每秒一万
    RocketMQ核心编程模型以及生产环境最佳实践
    zemax---中英文名词对照表(持续更新中)
    react等效memo的方法
    RML2016调制识别
    牛客网SQL159
    【现代机器人学】学习笔记十四:中文版印刷/翻译勘误
    RabbitMQ 教程 | 第8章 跨越集群的界限
    人脸识别系统之静态人脸识别
    GCP认证考试之Storage专题
  • 原文地址:https://blog.csdn.net/qq_41810415/article/details/126195074