LeetCode957 Prison Cells after N days

There are 8 prison cells in a row, and each cell is either occupied or vacant. if occupied, cells[i]=1, otherwise 0.
and we have the following rules:

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

example:
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]

there are few things we need to pay special attention when we try to understand this problem:

  1. the length of cells is 8, this is a fixed number, and it is 2 squares 3
  2. N might be as large as 10^9, which means, if we do this problem using brute force, the solution might TLL
  3. the stages of cells only contains two, 0s and 1s, which is exactly like computer.

solution1:
since N might be pretty large, so we can’t starting from times 1 to times N, No matter what the rules are, the states might be reappear after a certain times of proceeding(because we have fixed number of different states.)
but for different initial state, it might take different steps to reach back to this same state.
so we need to calculate the length of that. and based on N, we can get what we want after N steps.
This is the method called fast-forward.

and if the number of possible states is very large, say 10^10, and it’s even larger than N, then calculate the length of repetitive pattern is not acceptable.
but in this problem, there will be 2^8 number of possible states. so we can calculate the length of cycle.

however, think twice about it. each time we need to check if this is a repetitive pattern of initial state. this is time consuming.

Solution2:
we have a better solution, in stead of change each digit at a time for each transaction, we use bit map, based on the follow rule:
在这里插入图片描述

class Solution {
    public int[] prisonAfterNDays(int[] cells, int N) {

        HashMap<Integer, Integer> seen = new HashMap<>();
        boolean isFastForwarded = false;

        // step 1). convert the cells to bitmap
        int stateBitmap = 0x0;
        for (int cell : cells) {
            stateBitmap <<= 1;
            stateBitmap = (stateBitmap | cell);
        }

        // step 2). run the simulation with hashmap
        while (N > 0) {
            if (!isFastForwarded) {
                if (seen.containsKey(stateBitmap)) {
                    // the length of the cycle is seen[state_key] - N
                    N %= seen.get(stateBitmap) - N;
                    isFastForwarded = true;
                } else
                    seen.put(stateBitmap, N);
            }
            // check if there is still some steps remained,
            // with or without the fast forwarding.
            if (N > 0) {
                N -= 1;
                stateBitmap = this.nextDay(stateBitmap);
            }
        }

        // step 3). convert the bitmap back to the state cells
        int ret[] = new int[cells.length];
        for (int i = cells.length - 1; i >= 0; i--) {
            ret[i] = (stateBitmap & 0x1);
            stateBitmap = stateBitmap >> 1;
        }
        return ret;
    }

    protected int nextDay(int stateBitmap) {
        stateBitmap = ~(stateBitmap << 1) ^ (stateBitmap >> 1);
        // set the head and tail to zero
        stateBitmap = stateBitmap & 0x7e;
        return stateBitmap;
    }
}
posted @ 2020-07-30 08:59  EvanMeetTheWorld  阅读(25)  评论(0)    收藏  举报