zoukankan      html  css  js  c++  java
  • 双指针(最长连续不重复子序列 数组元素的目标和)

    首先看双指针的的模板

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

    最简单的应用可以求字符串中单词的个数,假设每个单词后都有一个空格

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char s[1010];
    
        gets(s);
    
        int n = strlen(s);
        for(int i = 0; i < n; i++)
        {
            int j = i;
            while(j < n && s[j] != ' ') j++;
    
            for(int k = i; k < j; k++) cout << s[k];
            cout << endl;
            i = j; 
        }
    
        system("pause");
        return 0;
    }
    

    其他例题

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

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

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

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

    数据范围
    1 ≤ n ≤ 100000
    输入样例:
    5
    1 2 2 3 5
    输出样例:
    3

    :首先用a数组来存放总序列,运用双指针i指针在前一直走,j指针在后,用s数组来记录数字是否出现过,如果 s[a[i]] > 1 则证明出现过这个数字,那么j数组就往后走,即 j++ ,同时
    相应的 s[a[j]]-- 直到没有重复数字,同时res不断更新, res = max(res, i-j+1)

    代码

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int a[100010];
    int s[100010];
    
    int main()
    {
        int n, res = 0;
    
        cin >> n;
        for(int i = 0; i < n; i++) cin >> a[i];
    
        for(int i = 0, j = 0; i < n; i++)
        {
            s[a[i]]++;
            while(s[a[i]] > 1)
            {
                s[a[j]]--;
                j++;
            }
            res = max(res, i-j+1);
        }
        
        cout << res << endl;
        system("pause");
        return 0;
    }
    

    数组元素的目标和
    给定两个升序排序的有序数组A和B,以及一个目标值x。数组下标从0开始。
    请你求出满足A[i] + B[j] = x的数对(i, j)。

    数据保证有唯一解。

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

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

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

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

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

    思路:i指针从前往后走,j指针从后往前走,因为是有序数组,所以如果 a[i] + b[j] > x ,那么j就一直往前走,直到 a[i]+b[j] <= x 跳出循环,然后判断是否等于x,如果等于就结束。

    代码

    #include <iostream>
    
    using namespace std;
    
    const int N = 100010;
    int n, m, x;
    int a[N], b[N];
    
    int main()
    {
        scanf("%d%d%d", &n, &m, &x);
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        for(int j = 0; j < m; j++) scanf("%d", &b[j]);
    
        for(int i = 0, j = m-1; i < n; i++)
        {
            while(j >= 0 && a[i]+b[j] > x) j--;
            if(a[i]+b[j] == x)
            {
                printf("%d %d", i, j);
                break;
            }
        }
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/13406171.html
Copyright © 2011-2022 走看看