C++ 最短连续页数问题:双指针算法详解

问题描述:

假设一本教材中有 P 页,每页包含第 a[i] 个知识点,知识点会有所重复,现给出每页的知识点 a[i] 以及需要看的知识点数 K,请你求出能够看完全部 1~K 个知识点的最短连续页数。注意本题必有解,不存在不包含的知识点。

输入描述:

3 行,第 1 行包含 1 个数字 P, 代表页数的个数 P。

第 2 行包含 P 个数字, 代表教材每页中的知识点 a[i]。

第 3 行包含 1 个数字 K, 代表需要看完的 K 个知识点。

输出描述:

1 行,表示最少连续页数。

思路:双指针

  1. 先用一个哈希表记录每个知识点出现的位置,便于后面的查找。
  2. 用双指针维护一个区间,使区间内包含所有需要看的知识点。
  3. 每次向右移动右指针,直到区间包含了所有需要看的知识点,记录此时的区间长度,并向右移动左指针,缩小区间长度,直到不再包含所有需要看的知识点。在这个过程中,记录每个区间的最小长度,即为所求。

时间复杂度:O(n)

C++ 代码

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

int main() {
    int P, K;
    cin >> P >> K;
    vector<int> a(P);
    for (int i = 0; i < P; ++i) {
        cin >> a[i];
    }
    unordered_map<int, int> mp;
    for (int i = 0; i < P; ++i) {
        mp[a[i]] = i;
    }
    int left = 0, right = 0;
    int count = 0;
    int minLen = P;
    while (right < P) {
        if (mp.count(right + 1) && mp[right + 1] < left) {
            left = mp[right + 1];
        }
        if (mp.count(right + 1)) {
            ++count;
        }
        ++right;
        while (count == K) {
            minLen = min(minLen, right - left);
            if (mp.count(left) && mp[left] < right) {
                --count;
            }
            ++left;
        }
    }
    cout << minLen << endl;
    return 0;
}
C++ 最短连续页数问题:双指针算法详解

原文地址: https://www.cveoy.top/t/topic/opU0 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录