1、题目链接
https://leetcode.com/problems/prison-cells-after-n-days/
2、解题思路
题目意思是说,一个监狱有8个牢房(一个数组),这8个牢房在一排且首尾不相连,如果在第一天某个牢房左右相邻的两个牢房同时有人(数组的值为1)或者同时没人(数组的值为0),第二天该牢房就算有人,这么说可能有点绕,解析一下
我用3个牢房来比喻一下,只有以下这几种情况,牢房才会有人(即数组的值为1):
day1:
0——>0——>0
1——>0——>1
0——>1——>0
1——>1——>1
day2:
待定——>1——>待定
待定——>1——>待定
待定——>1——>待定
待定——>1——>待定
给你一个数组表示这8个牢房的初始状态,让你求出第N天这8个牢房的状态是怎样的,N<=2的9次方。看到数字这么大的,如果直接用循环来把每次的状态都遍历出来那肯定会超时,这个是毫无疑问的,通过这个我们也可以从侧面的知道这个肯定是有循环的,所以,循环遍历所有的肯定会重复遍历,对于这种情况我们通常的做法就是将状态保存在hashmap中,一遍历到hashmap中存在的状态,那么该节点就是循环的一个节点,我们就可以直接通过取模运算来算出结果。
3、代码
public int[] prisonAfterNDays(int[] cells, int N) {
Map<Integer, String> map = new HashMap<>();
int[] prisons = new int[cells.length];
int count = N;
int index = 1;
while (count > 0) {
int flag = 0;
for (int i = 0; i < cells.length; i++) {
if (i == 0) {
prisons[flag] = 0;
} else if (i == cells.length - 1) {
prisons[flag] = 0;
} else if (cells[i - 1] == cells[i + 1]) {
prisons[flag] = 1;
} else {
prisons[flag] = 0;
}
flag++;
}
count--;
String value = intToString(prisons, cells);
if (map.containsValue(value)) {
flag = 0;
value = map.get(N % map.size() == 0 ? map.size() : N % map.size());
String[] keys = value.split("");
for (String k : keys) {
prisons[flag++] = Integer.valueOf(k);
}
return prisons;
} else {
map.put(index++, value);
}
}
return prisons;
}
public String intToString(int[] prisons, int[] cells) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < prisons.length; i++) {
cells[i] = prisons[i];
sb.append(prisons[i]);
}
return sb.toString();
}