leetcode957. N 天后的牢房
阿新 • • 發佈:2018-12-16
8 間牢房排成一排,每間牢房不是有人住就是空著。
每天,無論牢房是被佔用或空置,都會根據以下規則進行更改:
- 如果一間牢房的兩個相鄰的房間都被佔用或都是空的,那麼該牢房就會被佔用。
- 否則,它就會被空置。
(請注意,由於監獄中的牢房排成一行,所以行中的第一個和最後一個房間無法有兩個相鄰的房間。)
我們用以下方式描述監獄的當前狀態:如果第 i
間牢房被佔用,則 cell[i]==1
,否則 cell[i]==0
。
根據監獄的初始狀態,在 N
天后返回監獄的狀況(和上述 N 種變化)。
--
思路:
如果是按照一般思路,根據前一天狀態,更新第二天狀態,邏輯會很清晰,但是會超時或溢位(當N=1000000000時),因為要生成N次陣列來儲存狀態。
優化辦法:
1、題幹是8個房間,沒個房間就0或1兩種狀態,所以8個房間最多一共也就 2的8次方 =256種狀態,
2、狀態是有限的,而 天數N可以是無窮大的,所以規律就在這256種之內。
3、最多生成256天的狀態, 在這之內,不斷尋找有無相同狀態的一天,如果有,那麼規律就出現了
1. 2. [3]. . . . k . . . . 256. . N
加入我們算出第k天的狀態,和第3天一致,那麼從k之後的未來所有狀態,都是處於 3到k 之間迴圈的。
步驟:
1. 新增第0天狀態到 list
2. 根據 list中的最後一天的狀態pre,再新增新的一天的狀態 cur
3. 檢視cur 在list 0~pre中有無重複,如果有,規律出現,返回出現的下標index,如果無 繼續上述步驟
4. (N-index)%(k-index) + index 即為結果的下標
//957. N 天后的牢房 public int[] prisonAfterNDays(int[] cells, int N) {if (N == 0) { return cells; } ArrayList<int[]> list = new ArrayList<>(); list.add(cells); int k = 1; //k為第一天 while (k <= N) { int[] cur = prisionStatus(list.get(k - 1));//根據昨天的狀態獲取今天的狀態 list.add(cur);//將今天的狀態新增至list int index = findStatus(list);//迴圈判斷list中是否存在已有狀態,如果有返回下標,無返回-1 if (index != -1) { //如果 index != -1 ,說明找到重複 , ps:此處存在 /by zero 異常 try { int res = (N - index) % (k - index); //結果的下標 return list.get(index + res); } catch (Exception e){ return list.get(index); //存在異常的情況是 index + 1 == cur ,也就是昨天和今天狀態一致,也意味著監獄狀態穩定,以後不會變化。 } } k++; } return list.get(list.size() - 1); } //根據昨天獲取當天監獄狀態 private int[] prisionStatus(int[] pre) { int[] cur = new int[pre.length]; cur[0] = 0; cur[cur.length - 1] = 0; for (int i = 1; i < pre.length - 1; i++) { if (pre[i - 1] == pre[i + 1]) { cur[i] = 1; } else { cur[i] = 0; } } return cur; } //迴圈判斷list中是否存在已有狀態,如果有返回下標,無 返回-1 private int findStatus(ArrayList<int[]> list) { for (int i = 0; i <= list.size() - 2; i++) { if (arrayIsSame(list.get(list.size() - 1), list.get(i))) { return i; } } return -1; } //判斷陣列是否一致 private boolean arrayIsSame(int[] a, int[] b) { if (a.length != b.length) { return false; } for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { return false; } } return true; }