目录
题目
类似来源:leetcode房间状态问题
解题思路
1、房间状态会循环出现:共8间房,每个房间有两个状态,总共有2^8种状态。所以状态会形成循环;
2、模拟状态:模拟每一天的状态state,每次迭代一天的情况。
- 对于每一天,更新剩余的天数(怎么更新在3中有部分考虑);
- 将当天状态更新,就是state - > nextDay(state).
3、更新剩余天数:
- 当前状态出现过的情形:stata1 经过周期 t 天又出现了,意味着循环周期比剩下天数小(或者等),那么将剩下天数N更新为 整除t的余数,就是N %= t。只需要关注周期t天内的第 N%t 天是啥状态;
- 当前状态未出现过:继续迭代下一天,N--;
代码
import java.util.HashMap;
public class Solution{
public int[] prisonAfterNDays(int[] cells, int N) {
// 保存状态的键值对 :<state, 剩余天数>
HashMap<Integer, Integer> seen = new HashMap();
// 状态state,逐位赋初值
int state = 0;
for (int i = 0; i < 8; ++i) {
if (cells[i] > 0)
state ^= 1 << i;
}
// 还有剩余天数,模拟一天
while (N > 0) {
// 当前状态出现过,周期t = seen.get(state) - N
if (seen.containsKey(state)) {
//更新N, N %= t ;
N %= seen.get(state) - N;
}
// 当前状态没出现过,将其存入保存状态的键值对,天数N--,更新状态
seen.put(state, N);
if (N >= 1) {
N--;
state = nextDay(state);
}
}
// Convert the state back to the required answer.
int[] ans = new int[8];
for (int i = 0; i < 8; ++i) {
if (((state >> i) & 1) > 0) {
ans[i] = 1;
}
}
return ans;
}
public int nextDay(int state) {
int ans = 0;
// We only loop from 1 to 6 because 0 and 7 are impossible,
// as those cells only have one neighbor.
// 根据规则更新状态
for (int i = 1; i <= 6; ++i) {
if (((state >> (i-1)) & 1) == ((state >> (i+1)) & 1)) {
ans ^= 1 << i;
}
}
return ans;
}
}