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;
    }
    
  • 相关阅读:
    OO第四单元总结
    OO第三单元总结
    OO第二单元总结
    OO第一单元总结
    面向对象第四单元总结
    面向对象第三单元总结
    面向对象第二单元的总结
    操作系统lab3实验总结
    操作系统lab2实验总结——Part2
    操作系统lab2实验总结——Part1
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/13406171.html
Copyright © 2011-2022 走看看