跑上来还是先直接暴力搜索,用一个数组标记了一下状态,耗时耗空间,后来再做了改进。
原题传送门
【题目描述】
【示例】
【解题过程】
【思路】
先用flag数组,标记所有灯泡的开关情况,然后记录当前打开的最右边的灯泡,每次遍历flag数组,发现right前面有没有打开的灯,就结束遍历。
【代码】
根据上面的思路,写出了第一个版本的代码:
class Solution {
public:
int numTimesAllBlue(vector<int>& light) {
int ans=0;
int k=light.size();
int* flag=new int[k+1];
int fl=0;
int right=0;
for(int i=0;i<light.size();i++){
flag[light[i]]=1;
if(right<light[i]){
right=light[i];
}
fl=0;
for(int j=1;j<right;j++){
if(flag[j]!=1){
fl=1;
break;
}
}
if(fl==0){
ans+=1;
}
}
return ans;
}
};
运行结果:
这个代码,时间空间复杂度都比较高。
【改进版代码】
在想要怎么改的时候,本来想通过最右侧灯的序号和已打开灯的数量的关系减少循环次数,结果发现,只要记录了打开的最右边的灯的序号,只有当打开的灯的数量和最右边的灯序号相等时,才会全部变蓝,甚至都不需要标记数组!!因此,修改了代码:
class Solution {
public:
int numTimesAllBlue(vector<int>& light) {
int ans=0;
int right=0;
for(int i=0;i<light.size();i++){
if(right<light[i]){
right=light[i];
}
if(right==(i+1)){//已打开的最右边的灯的序号==现在打开的灯的数量
ans+=1;
}
}
return ans;
}
};
执行结果:
最初版耗时1168ms,后来试图减少些循环,耗时616ms,最后,只需要64ms.