zoukankan      html  css  js  c++  java
  • [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 题目总结

  • 相关阅读:
    Python通过多线程实现 `异步`
    Linux(六) 处理用户输入
    Linux(五) 更多结构化命令
    Linux(四) 使用结构化命令
    Linux(三) 科学计算
    Linux(二) Shell脚本
    python 登陆接口
    学习的小建议
    干货
    ThinkPhp5 自定义异常处理类
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13233621.html
Copyright © 2011-2022 走看看