求数组中包含所有数字的最小区间

算法题:
一个由若干个取值范围在【1,2^31-1】的整数构成的长度为N的数字序列,其中N<5000000;求该数字序列上一段最小的连续区间的长度,要求该区间内正好包含了该N个数字序列所有不同的数字,如果存在多个这样的区间,按照出现的顺序输出所有的区间骑士和结束位置,序列的位置编号从1到N,其中最小的区间长度不会超过10000。

输入:
10
1
1
3
4
6
6
5
1
3
3

输出:
6 ,3
[2,7] [3,8] [4,9]

解题思路:使用队列

#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>

using namespace std;

int main() {
    int N;
    vector<int> vec;
    set<int> data;
    cin >> N;
    for (int i = 0; i < N; i++) {
        int aa;
        cin >> aa;
        vec.push_back(aa);
        data.insert(aa);
    }

    int length = N;
    vector<int> ans;
    int start = 1, end = 0;
    map<int, int> mm;
    queue<int> dd;
    for (int i = 0; i < N; i++) {
        if (!dd.empty() && dd.front() == vec[i]) {
            dd.pop();
            dd.push(vec[i]);
            end++;
            start++;
            while (mm.size() == data.size() && mm[dd.front()] > 1) {
                --mm[dd.front()];
                dd.pop();
                start++;
            }
        }
        else {
            dd.push(vec[i]);
            ++mm[vec[i]];
            end++;
        }
        if (mm.size() == data.size() && end - start + 1 <= length) {
            if (end - start + 1 < length) {
                length = end - start + 1;
                ans.clear();
            }
            ans.push_back(start);
            ans.push_back(end);
        }
    }
    cout << length << "," << ans.size() / 2 << endl;
    for (int i = 0; i < ans.size(); i += 2) {
        cout << '[' << ans[i] << ',' << ans[i + 1] << ']';
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014253011/article/details/82708825