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:

348. Design Tic-Tac-Toe_第1张图片
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);
 */

你可能感兴趣的:(348. Design Tic-Tac-Toe)