1. 程式人生 > >Leetcode_957_Prison Cells After N Days

Leetcode_957_Prison Cells After N Days

由最後的提示“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;
    }
};

另外,我覺得迴圈不一定從第一位開始,這可能也是一個坑(證明不來,但憑直覺就是……)如果有誤,或您能夠證明,歡迎批評指正,謝謝(還望各位大佬不吝賜教)