[Leetcode] 289. Game of Life

这一题如果不是in place的话难度连easy都没有。就是列举几种不同的周边格子的状态然后判断当前格子的状态。具体状态看题意就知道了。要做in place的话也不难。因为原来的状态只有1和0两种,所以其实作为一个int你还有很多的空间可以发挥。譬如我们做状态判断的时候,我们取整型数的第二位去储存接下来即将变成的状态,然后依旧用第一位去做状态更迭的判断,这样就避免了Follow up 1中提到的问题。根据上述描述,可以得到代码如下:

    private void _setNextByNeighbor(int[][] board, int x, int y) {
        int livesCnt = 0;
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                if (i == 0 && j == 0) continue;
                if ((x + i < 0) || (x + i >= board.length)) continue;
                if ((y + j < 0) || (y + j >= board[0].length)) continue;
                
                if (board[x + i][y + j] % 2 == 1) livesCnt++;
            }
        }
        
        if ((board[x][y] == 1 && (livesCnt == 3 || livesCnt == 2))
            || (board[x][y] == 0 && livesCnt == 3)) {
            board[x][y] += 2;
        }
    }

    public void gameOfLife(int[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                this._setNextByNeighbor(board, i, j);
            }
        }
        
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                board[i][j] >>= 1;
            }
        }
    }

关于follow up 2,其实就是说如果棋盘无比巨大,内存一次过放不下怎么办?那就写进文件里一行行的读再分析呗。这一题要求内存最少能够读取三行的内容,这样你就可以先读三行,然后放进最上面的一行,然后读下一行继续。譬如先读1,2,3行,然后处理过之后放回第一行,读第四行,然后再放第二行,读第五行.....恰好,我还写过对应的代码,原因不详

public void calculateThreeLines(int[][] board) {
		for (int i = 0; i < board[1].length; i++) {
			int liveCnt = 0;
			for (int j = -1; j <= 1; j++) {
				for (int k = -1; k <= 1; k++) {
					if (j == 0 && k == 0) continue; 
					if (board[1 + j] == null) continue;
					if (k + i < 0 || k + i >= board[1].length) continue;

					if (board[1 + j][k + i] % 2== 1) liveCnt++;
				}
			}

			if (liveCnt >= 2 && liveCnt <= 3 && board[1][i] == 1) board[1][i] += 2;
			else if (board[1][i] == 0 && liveCnt == 3) board[1][i] += 2;
		}
	}

	public void convertOneLine(int[] outputLine) {
		for (int i = 0; i < outputLine.length; i++) outputLine[i] /= 2;
	}

	public void gameOfLife() {
		int[][] board = new int[3][];
		board[1] = readLine();
		while (board[1] != null) {
			board[2] = readLine();
			calculateThreeLines(board);
			if (board[0] != null) {
				convertOneLine(board[0]);
				writeLine(board[0]);
			}

			board[0] = board[1];
			board[1] = board[2];
		}
		if (board[0] != null) {
			convertOneLine(board[0]);
			writeLine(board[0]);			
		}
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值