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

Accepted  16,671  Submissions  44,652

二 分析

   照例是先看英语,大意是这样的:一排8间牢房,房间的状态要么是占着,要么是空着。

每天,房间的状态会修改,它遵循的规则如下:

  • 如果它相邻的两间牢房都为占用,或者都为空着,那么它就是占用。
  • 否则就是空着。

注意,它是一个数组,第一个跟最后一个没有两个邻居。

用数组表示,其中cells[i] =1 表示占用,cells[i]=0 表示空着。

给个初始状态的数组,求N天后它的状态。

后面给出了例子。当我看到例2 N=1000000000 时,想起了之前看的程序员数学提到的,无穷大的问题数据要找规律。

所以,我们先按照题目要求,尝试去求50天后的数组。

int[] cells = {0,1,0,1,1,0,0,1};
        int[] res =prisonAfterNDays(cells,50);

 public static int[] prisonAfterNDays(int[] cells, int N) {
	        
		
		 while(N>0){
			 int[] results = new int[8];
			 results[0] =0;			
			 for(int i=1;i<cells.length-1;i++ ){
				 
				 if(cells[i-1]==cells[i+1] ){
					 results[i]=1;
				 }else{
					 results[i] =0;
				 }
				 
			 }
			 results[7]=0;
		     N--;
		     System.out.println((50-N)+":"+JSON.toJSON(results));
		     cells = results;
		 }
		 
		 return cells;
		 
		 
	    }

实现相对简单:

results[0],results[7] 分别是首末,迭代后一定为0.

其余从1开始判断,1-6,判断cells[i-1],cells[i+1]是否相等

看着不难,但是调试的过程还是不顺利,我一看犯个错,把results不是每次生成,就导致跟cells混了,第一天还对,以后的就错了。

输出结果:

1:[0,1,1,0,0,0,0,0]
2:[0,0,0,0,1,1,1,0]
3:[0,1,1,0,0,1,0,0]
4:[0,0,0,0,0,1,0,0]
5:[0,1,1,1,0,1,0,0]
6:[0,0,1,0,1,1,0,0]
7:[0,0,1,1,0,0,0,0]
8:[0,0,0,0,0,1,1,0]
9:[0,1,1,1,0,0,0,0]
10:[0,0,1,0,0,1,1,0]
11:[0,0,1,0,0,0,0,0]
12:[0,0,1,0,1,1,1,0]
13:[0,0,1,1,0,1,0,0]
14:[0,0,0,0,1,1,0,0]
15:[0,1,1,0,0,0,0,0]
16:[0,0,0,0,1,1,1,0]
17:[0,1,1,0,0,1,0,0]
18:[0,0,0,0,0,1,0,0]
19:[0,1,1,1,0,1,0,0]
20:[0,0,1,0,1,1,0,0]
21:[0,0,1,1,0,0,0,0]
22:[0,0,0,0,0,1,1,0]
23:[0,1,1,1,0,0,0,0]
24:[0,0,1,0,0,1,1,0]
25:[0,0,1,0,0,0,0,0]
26:[0,0,1,0,1,1,1,0]
27:[0,0,1,1,0,1,0,0]
28:[0,0,0,0,1,1,0,0]
29:[0,1,1,0,0,0,0,0]
30:[0,0,0,0,1,1,1,0]
31:[0,1,1,0,0,1,0,0]
32:[0,0,0,0,0,1,0,0]
33:[0,1,1,1,0,1,0,0]
34:[0,0,1,0,1,1,0,0]
35:[0,0,1,1,0,0,0,0]
36:[0,0,0,0,0,1,1,0]
37:[0,1,1,1,0,0,0,0]
38:[0,0,1,0,0,1,1,0]
39:[0,0,1,0,0,0,0,0]
40:[0,0,1,0,1,1,1,0]
41:[0,0,1,1,0,1,0,0]
42:[0,0,0,0,1,1,0,0]
43:[0,1,1,0,0,0,0,0]
44:[0,0,0,0,1,1,1,0]
45:[0,1,1,0,0,1,0,0]
46:[0,0,0,0,0,1,0,0]
47:[0,1,1,1,0,1,0,0]
48:[0,0,1,0,1,1,0,0]
49:[0,0,1,1,0,0,0,0]
50:[0,0,0,0,0,1,1,0]
[0,0,0,0,0,1,1,0]
可以发现,这个是有周期的,就是14天会重复出现。

所以我们改进下程序,把N对14天求余。就可以大幅减少计算次数。

class Solution {
    public int[] prisonAfterNDays(int[] cells, int N) {
        N = N%14;
		 if(N ==0){
			 N =14;
		 }
		
		 while(N>0){
			 int[] results = new int[8];
			 results[0] =0;			
			 for(int i=1;i<cells.length-1;i++ ){
				 
				 if(cells[i-1]==cells[i+1] ){
					 results[i]=1;
				 }else{
					 results[i] =0;
				 }
				 
			 }
			 results[7]=0;
		     N--;		    
		     cells = results;
		 }
		 
		 return cells;
    }
}

Runtime: 1 ms, faster than 99.97% of Java online submissions for Prison Cells After N Days.

Memory Usage: 36.4 MB, less than 99.61% of Java online submissions forPrison Cells After N Days.

感慨一下:真的自己不聪明,一个题目做2小时,那些做题跟切菜一版的大神是怎么修炼成的?

功不唐捐,日拱一卒。之前你看的书,说不定那会就有用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值