由最后的提示“1 <= N <= 10^9
”可知如果强行将每一个N取值的情况都求一遍,必然超时
但乍一看,本题要想求得其中一项,必须求上一项,有递推公式的感觉
所以,第一反应把希望放在从递推关系中求出“通项公式”或者存在周期性的规律
进一步审题,从“cells.length == 8
”,同时,“行中的第一个和最后一个房间无法有两个相邻的房间”可知,从N=1开始,头尾的值均为0,故,最多的变化为2^6,显然,当N足够大时,会出现重复的情况
由递推关系可知,显然,当一项确定时,它的下一项也随之确定
所以,很开心地发现,确实存在周期性的规律
所以,当找到重复的情况出现之日,就是新的周期开始之时
于是决定借助基于 Hash实现的map结构
由于 cell数组是由1,0值组成的,曾经想用int类型表示0-1串作为map的key,但发现00011000与11000000表示是相同的,于是放弃了这种类型的键值,而采用了string
class Solution {
public:
vector<int> prisonAfterNDays(vector<int>& cells, int N) {
vector<int> tmp(cells.begin(),cells.end());
map<string,int> storage;
map<string,int>::iterator GetKey;
vector<vector<int>> memory;
string mark;
int T,real;
tmp[0]=0;
tmp[7]=0;
int i,j;
for(j=0;j<N;j++)
{
mark="";
for(i=1;i<7;i++)
{
tmp[i]=cells[i-1]==cells[i+1]?1:0;
mark=mark+char(tmp[i]+'0');
}
GetKey=storage.find(mark);
if(GetKey!=storage.end())
{
T=j-GetKey->second;
real=N-GetKey->second;
return real%T==0?memory[GetKey->second-1+T]:memory[GetKey->second-1+real%T];
}
storage[mark]=j;
memory.push_back(tmp);
cells.assign(tmp.begin(),tmp.end());
}
return cells;
}
};
另外,我觉得循环不一定从第一位开始,这可能也是一个坑(证明不来,但凭直觉就是……)如果有误,或您能够证明,欢迎批评指正,谢谢(还望各位大佬不吝赐教)