求陣列中包含所有數字的最小區間
阿新 • • 發佈:2019-01-07
演算法題:
一個由若干個取值範圍在【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;
}