348. Design Tic-Tac-Toe

Description

Design a Tic-tac-toe game that is played between two players on a n x n grid.

You may assume the following rules:

  1. A move is guaranteed to be valid and is placed on an empty block.
  2. Once a winning condition is reached, no more moves is allowed.
  3. A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game.

Example:

image.png

Follow up:
Could you do better than O(n2) per move() operation?

Solution

2D board, time O(n), space O(n ^ 2)

用一个2D board存储状态,每次操作之后,检查是否符合胜利条件。

class TicTacToe {
    private int[][] board;
    private int n;
    /** Initialize your data structure here. */
    public TicTacToe(int n) {
        board = new int[n][n];
        this.n = n;
    }
    
    /** Player {player} makes a move at ({row}, {col}).
        @param row The row of the board.
        @param col The column of the board.
        @param player The player, can be either 1 or 2.
        @return The current winning condition, can be either:
                0: No one wins.
                1: Player 1 wins.
                2: Player 2 wins. */
    public int move(int row, int col, int player) {
        board[row][col] = player;
        
        if (checkRow(row, player) || checkCol(col, player) 
            || checkDiamond(row, col, player)) {
            return player;
        }
        
        return 0;
    }
    
    public boolean checkRow(int row, int player) {
        for (int c = 0; c < n; ++c) {
            if (board[row][c] != player) {
                return false;
            }
        }
        
        return true;
    }
    
    public boolean checkCol(int col, int player) {
        for (int r = 0; r < n; ++r) {
            if (board[r][col] != player) {
                return false;
            }
        }
        
        return true;
    }
    
    public boolean checkDiamond(int row, int col, int player) {
        return (row == col && checkLeftDiamond(player)) 
            || (row + col == n - 1 && checkRightDiamond(player));
    }
    
    public boolean checkLeftDiamond(int player) {
        for (int r = 0; r < n; ++r) {
            if (board[r][r] != player) {
                return false;
            }
        }
        
        return true;
    }
    
    public boolean checkRightDiamond(int player) {
        for (int r = 0; r < n; ++r) {
            if (board[r][n - r - 1] != player) {
                return false;
            }
        }
        
        return true;
    }
    
}

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe obj = new TicTacToe(n);
 * int param_1 = obj.move(row,col,player);
 */

1D array, time O(1), space O(n)

每个player可以对应一个数值,例如对应1和-1,对于每行、列、对角线来说,只需要保存一个sum就行了。

class TicTacToe {

    private int[] rows;
    private int[] cols;
    private int dia;
    private int antiDia;
    private int n;
    /** Initialize your data structure here. */
    public TicTacToe(int n) {
        this.n = n;
        rows = new int[n];
        cols = new int[n];
    }
    
    /** Player {player} makes a move at ({row}, {col}).
        @param row The row of the board.
        @param col The column of the board.
        @param player The player, can be either 1 or 2.
        @return The current winning condition, can be either:
                0: No one wins.
                1: Player 1 wins.
                2: Player 2 wins. */
    public int move(int row, int col, int player) {
        int val = player == 1 ? 1 : -1; // tricky
        rows[row] += val;
        cols[col] += val;
        dia += row == col ? val : 0;
        antiDia += row + col == n - 1 ? val : 0;
        
        int target = n * val;
        if (rows[row] == target || cols[col] == target 
            || dia == target || antiDia == target) {
            return player;
        }
        
        return 0;
    }
}

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe obj = new TicTacToe(n);
 * int param_1 = obj.move(row,col,player);
 */
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,434评论 0 10
  • 1.创建桥接文件 首先我们直接在当前项目上新增加一个文件,语言选择swift,然后创建,此时,会弹出一个框,询问你...
    用心在飞阅读 385评论 0 0
  • 本报讯(记者 付琦霓)10月11中午,我校体育部所举办的校篮球赛在体育馆拉开帷幕,体育学院的老师唐志鹏致辞发言,提...
    霓菇凉阅读 175评论 0 2
  • 其实有太阳就会有月亮,有冬天就会有夏天,有情天就会有雨天,现实是无法改变的,而我们却可以掌握自己的心态,去笑对我们...
    L_Yao阅读 193评论 0 0