题目大意:
已知有n个灯泡。每个灯泡有off,on和变蓝三个状态。on灯泡要变蓝的充要条件是:所有on的灯泡必须从左到右排列。已知刚开始所有的灯泡都是off,给定一个按照时间变化的亮灯的序列,问我们总共有哪几个时刻所有on的灯泡是蓝的。
解题思路:
用数组记录每个灯泡on着的话,最左和最右可以延伸到哪里。然后询问当前灯泡on是否能够延续到0,另外询问是否有灯泡比它最右的灯泡还要远。
其中最左和最右我们可以用lmost,rmost表示。每次其实我们只用维护连续on区间的端点就可以了。
if(p-1>=0 && mv[p-1])lmost[p]=lmost[p-1];
if(p+1<n && mv[p+1])rmost[p]=rmost[p+1];
rmost[lmost[p]]=rmost[p];
lmost[rmost[p]]=lmost[p];
然后我们还需要维护一个区间最右端点,用来判断最远是否延伸到比当前rmost[p]还要远。
代码:
class Solution {
public:
int numTimesAllBlue(vector<int>& light) {
int n=light.size();
vector<int> lmost(n);
vector<int> rmost(n);
vector<int> mv(n,0);
for(int i=0;i<n;i++)lmost[i]=i;
for(int i=0;i<n;i++)rmost[i]=i;
int ans=0;
int maxp=-1;
for(int i=0;i<n;i++){
int p=light[i];
p--;
maxp=max(maxp,p);
mv[p]=1;
if(p-1>=0 && mv[p-1])lmost[p]=lmost[p-1];
if(p+1<n && mv[p+1])rmost[p]=rmost[p+1];
rmost[lmost[p]]=rmost[p];
lmost[rmost[p]]=lmost[p];
if(p && !mv[p-1])continue;
if(p){
if(lmost[p]>0)continue;
}
if(maxp==rmost[p])ans++;
}
return ans;
}
};
第二种思路:
其实我们每次只要最右的端点等于点亮的灯泡数,才能够让这个时刻变蓝。