【Lintcode】1301. Game of Life

题目地址:

https://www.lintcode.com/problem/game-of-life/description

给定一个 0 − 1 0-1 01矩阵,按照下面的要求改变该矩阵:
1、若某处为 1 1 1,如果其八个方向的邻居(如果在边界那么邻居会少于八个)有 2 2 2 3 3 3 1 1 1,则该处不改变,否则改为 0 0 0
2、若某处为 0 0 0,并且其八个方向的邻居恰好有 3 3 3 1 1 1,则该处改为 1 1 1,否则不变。
求改变后的矩阵。

为了保存改变之前每个位置的状态,我们用二进制的两个位来解决这个问题。 0 = 00 0=00 0=00表示原来该处是 0 0 0,将要变为 0 0 0 1 = 01 1=01 1=01表示原来该处是 1 1 1,将要变为 0 0 0 2 = 10 2=10 2=10表示原来该处是 0 0 0,将要变为 1 1 1 3 = 11 3=11 3=11表示原来该处是 1 1 1,将要变为 1 1 1。这样就可以先将每个位置先变为上述二进制表示来做标记,起过渡作用,然后最后再将每个位置置为 0 0 0或者 1 1 1。代码如下:

public class Solution {
    /**
     * @param board: the given board
     * @return: nothing
     */
    public void gameOfLife(int[][] board) {
        // Write your code here
        // 判空
        if (board == null || board.length == 0 || board[0].length == 0) {
            return;
        }
        // 先将每个位置变为中间过渡状态
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                int curState = board[i][j], liveNeighbors = computeLiveNeighbors(board, i, j);
                // 如果当前状态是1,并且有2或3个值为1的邻居,则说明该处的1要变为1,所以置为(11) = 3;
                // 否则该处的1要变为0,置为(01) = 1也就是不变;
                // 如果当前状态是0,则当且仅当其有3个值为1的邻居,才会变成1,所以置为(10) = 2
                if (curState == 1 && (liveNeighbors == 2 || liveNeighbors == 3)) {
                    board[i][j] = 3;
                } else if (liveNeighbors == 3) {
                    board[i][j] = 2;
                }
            }
        }
        
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                board[i][j] = ((board[i][j] & 2) == 2) ? 1 : 0;
            }
        }
    }
    
    // 算一下board[x][y]有多少个值为1的邻居
    private int computeLiveNeighbors(int[][] board, int x, int y) {
        int count = 0;
        int[][] dir = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
        for (int i = 0; i < dir.length; i++) {
            int nextX = x + dir[i][0], nextY = y + dir[i][1];
            if (inBound(board, nextX, nextY)) {
            	// 一个位置的状态是1当且仅当其二进制的最低位等于1
                int curState = board[nextX][nextY] & 1;
                count += curState;
            }
        }
        
        return count;
    }
    
    private boolean inBound(int[][] board, int x, int y) {
        return 0 <= x && x < board.length && 0 <= y && y < board[0].length;
    }
}

时间复杂度 O ( m n ) O(mn) O(mn),空间 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值