leetcode 5353 灯泡开关(规律)

题目大意:

已知有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;
    }
};

第二种思路:

其实我们每次只要最右的端点等于点亮的灯泡数,才能够让这个时刻变蓝。

https://leetcode-cn.com/submissions/detail/52037095/

发布了171 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/FrostMonarch/article/details/104736768