一本书中,每一页有一个知识点,希望连续的看一些页数,能包含所有的知识点。请问最短的连续页数是几页?
同样可以用尺取法来求解。首先用set来统计不同知识点的个数。
然后定义s,t,t不断右移动,然后压入map, map的索引是知识点编号,值是知识点现在在此子序列中出现的个数。如果压入map之前,
值为0,说明找到一个新的知识点,num++,直到num为知识点总的的个数为止
然后扣去s,再把s右移动一位,吧扣掉的在map中数量减去1,如果剪完之后值为0,书名知识点消失,num--
循环结束,再考虑t的右移的问题。
题源来自《挑战程序竞赛》第二版149页,示例程序写的足够简洁明了效率高,可以借鉴参考:
//
// 149_reading problem.cpp
// changlle
//
// Created by user on 1/9/16.
// Copyright (c) 2016 user. All rights reserved.
//
#include <iostream>
#include <set>
#include <map>
using namespace std;
int P=5;
int a[5]={1,8,8,8,1};
void solve() {
set<int> all;
for (int i=0;i<P;i++) {
all.insert(a[i]);
}
int n=all.size(); //统计有多少个不同的元素
int s=0,t=0,num=0;
map<int,int> count; //知识点及对应出现的个数。
int res=P;
for (;;){
while (t<P && num<n) {
if (count[a[t++]]++==0)
num++;
}
if (num<n) break; //到头还没有找齐所有知识点
res=min(res,t-s);
if (--count[a[s++]]==0)
num--;
}
cout<<res<<endl;
}
int main() {
solve();
return 0;
}