[LeetCode] 957. Prison Cells After N Days

There are 8 prison cells in a row, and each cell is either occupied or vacant.

Each day, whether the cell is occupied or vacant changes according to the following rules:

  • If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.
  • Otherwise, it becomes vacant.

(Note that because the prison is a row, the first and the last cells in the row can't have two adjacent neighbors.)

We describe the current state of the prison in the following way: cells[i] == 1 if the i-th cell is occupied, else cells[i] == 0.

Given the initial state of the prison, return the state of the prison after N days (and N such changes described above.)

Example 1:

Input: cells = [0,1,0,1,1,0,0,1], N = 7
Output: [0,0,1,1,0,0,0,0]
Explanation: 
The following table summarizes the state of the prison on each day:
Day 0: [0, 1, 0, 1, 1, 0, 0, 1]
Day 1: [0, 1, 1, 0, 0, 0, 0, 0]
Day 2: [0, 0, 0, 0, 1, 1, 1, 0]
Day 3: [0, 1, 1, 0, 0, 1, 0, 0]
Day 4: [0, 0, 0, 0, 0, 1, 0, 0]
Day 5: [0, 1, 1, 1, 0, 1, 0, 0]
Day 6: [0, 0, 1, 0, 1, 1, 0, 0]
Day 7: [0, 0, 1, 1, 0, 0, 0, 0]

Example 2:

Input: cells = [1,0,0,1,0,0,1,0], N = 1000000000
Output: [0,0,1,1,1,1,1,0]

Note:

  1. cells.length == 8
  2. cells[i] is in {0, 1}
  3. 1 <= N <= 10^9

N天后的牢房。

8 间牢房排成一排,每间牢房不是有人住就是空着。每天,无论牢房是被占用或空置,都会根据以下规则进行更改:

  • 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用。
  • 否则,它就会被空置。

(请注意,由于监狱中的牢房排成一行,所以行中的第一个和最后一个房间无法有两个相邻的房间。)

我们用以下方式描述监狱的当前状态:如果第 i 间牢房被占用,则 cell[i]==1,否则 cell[i]==0。

根据监狱的初始状态,在 N 天后返回监狱的状况(和上述 N 种变化)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/prison-cells-after-n-days
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

暴力解不难想,但是由于N有可能非常大,所以需要找规律。为什么一定有规律呢,因为8个牢房,每个牢房的状态只有0和1,所以最坏也就只有2^8 = 256种组合。如果N大于256,则一定有循环。

首先创建一个nextDay函数,计算下一天的牢房状态;其次需要一个hashset,记录是否有重复的状态,记得在Java里需要把数组转化成字符串再存入hashset。当找到循环次数之后可以立即停止,然后用N % 循环次数。

时间O(1) - 最多255次计算

空间O(n) - hashset

Java实现

 1 class Solution {
 2     public int[] prisonAfterNDays(int[] cells, int N) {
 3         // corner case
 4         if (cells == null || cells.length == 0 || N <= 0) {
 5             return cells;
 6         }
 7 
 8         // normal case
 9         boolean hasCycle = false;
10         int cycle = 0;
11         HashSet<String> set = new HashSet<>();
12         for (int i = 0; i < N; i++) {
13             int[] next = nextDay(cells);
14             String key = Arrays.toString(next);
15             if (!set.contains(key)) {
16                 set.add(key);
17                 cycle++;
18             } else {
19                 hasCycle = true;
20                 break;
21             }
22             cells = next;
23         }
24         if (hasCycle) {
25             N %= cycle;
26             for (int i = 0; i < N; i++) {
27                 cells = nextDay(cells);
28             }
29         }
30         return cells;
31     }
32 
33     private int[] nextDay(int[] cells) {
34         int[] temp = new int[cells.length];
35         for (int i = 1; i < cells.length - 1; i++) {
36             temp[i] = cells[i - 1] == cells[i + 1] ? 1 : 0;
37         }
38         return temp;
39     }
40 }

 

JavaScript实现

 1 /**
 2  * @param {number[]} cells
 3  * @param {number} N
 4  * @return {number[]}
 5  */
 6 var prisonAfterNDays = function (cells, N) {
 7     var list = [];
 8     var num = N;
 9     for (var j = 1; j <= N; j++) {
10         var arr = [];
11         for (var i = 0; i < cells.length; i++) {
12             if (i == 0 || i == cells.length - 1) {
13                 arr[i] = 0;
14             } else {
15                 if (cells[i - 1] == cells[i + 1]) {
16                     arr[i] = 1;
17                 } else {
18                     arr[i] = 0;
19                 }
20             }
21         }
22         list.push(arr); // 存放数组,直到找到周期值
23         cells = arr;
24         if (j > 1 && arr.join('') == list[0].join('')) {
25             // console.log(j)
26             // console.log(arr)  15=1  16=2   找出周期关系
27             num = j - 1; // 获取周期
28             break;
29         }
30     }
31     var n = N % num; // 周期内的位置
32     if (n == 0) {
33         return list[num - 1];
34     } else {
35         return list[n - 1];
36     }
37 };

 

LeetCode 题目总结

posted @ 2020-07-04 06:20  CNoodle  阅读(300)  评论(0编辑  收藏  举报