Assume the following rules are for the tic-tac-toe game on an n x n
board between two players:
- A move is guaranteed to be valid and is placed on an empty block.
- Once a winning condition is reached, no more moves are allowed.
- A player who succeeds in placing
n
of their marks in a horizontal, vertical, or diagonal row wins the game.
Implement the TicTacToe
class:
-
TicTacToe(int n)
Initializes the object the size of the boardn
. -
int move(int row, int col, int player)
Indicates that player with idplayer
plays at the cell(row, col)
of the board. The move is guaranteed to be a valid move.
Follow up:
Could you do better than O(n2)
per move()
operation?
Example 1:
Input ["TicTacToe", "move", "move", "move", "move", "move", "move", "move"] [[3], [0, 0, 1], [0, 2, 2], [2, 2, 1], [1, 1, 2], [2, 0, 1], [1, 0, 2], [2, 1, 1]] Output [null, 0, 0, 0, 0, 0, 0, 1] Explanation TicTacToe ticTacToe = new TicTacToe(3); Assume that player 1 is "X" and player 2 is "O" in the board. ticTacToe.move(0, 0, 1); // return 0 (no one wins) |X| | | | | | | // Player 1 makes a move at (0, 0). | | | | ticTacToe.move(0, 2, 2); // return 0 (no one wins) |X| |O| | | | | // Player 2 makes a move at (0, 2). | | | | ticTacToe.move(2, 2, 1); // return 0 (no one wins) |X| |O| | | | | // Player 1 makes a move at (2, 2). | | |X| ticTacToe.move(1, 1, 2); // return 0 (no one wins) |X| |O| | |O| | // Player 2 makes a move at (1, 1). | | |X| ticTacToe.move(2, 0, 1); // return 0 (no one wins) |X| |O| | |O| | // Player 1 makes a move at (2, 0). |X| |X| ticTacToe.move(1, 0, 2); // return 0 (no one wins) |X| |O| |O|O| | // Player 2 makes a move at (1, 0). |X| |X| ticTacToe.move(2, 1, 1); // return 1 (player 1 wins) |X| |O| |O|O| | // Player 1 makes a move at (2, 1). |X|X|X|
Constraints:
2 <= n <= 100
- player is
1
or2
. 0 <= row, col < n
-
(row, col)
are unique for each different call tomove
. - At most
n2
calls will be made tomove
.
Ideas:
for each time player play, we check row, col, dig and anti dig. T: O(n) per move
class TicTacToe: def __init__(self, n: int): """ Initialize your data structure here. """ self.n = n self.board= [[0] * n for _ in range(n)] def move(self, row: int, col: int, player: int) -> int: """ 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. """ self.board[row][col] = player if self.checkRow(row, player) or self.checkCol(col, player) or (row == col and self.checkDig(player)) or (row == self.n - 1 - col and self.checkAntiDig(player)): return player return 0 def checkRow(self, row, player): for i in range(self.n): if self.board[row][i] != player: return False return True def checkCol(self, col, player): for i in range(self.n): if self.board[i][col] != player: return False return True def checkDig(self, player): for i in range(self.n): if self.board[i][i] != player: return False return True def checkAntiDig(self, player): for i in range(self.n): if self.board[i][self.n - i - 1] !=player: return False return True
2. T: O(1), S: O(n), 利用row 和col来记录每行及每列每个player放的个数,如果 == self.n, 那么win。
class TicTacToe: def __init__(self, n: int): """ Initialize your data structure here. """ self.n = n self.board= [[0] * n for _ in range(n)] self.row = [[0] * n for _ in range(2)] # 0 : player 1 self.col = [[0] * n for _ in range(2)] # 0 : player 1 self.dig = [0] * 2 self.anti = [0] * 2 def move(self, row: int, col: int, player: int) -> int: """ 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. """ self.board[row][col] = player self.row[player - 1][row] += 1 self.col[player - 1][col] += 1 if row == col: self.dig[player - 1] += 1 if row == self.n - col - 1: self.anti[player - 1] += 1 if self.n in [self.row[player - 1][row], self.col[player - 1][col], self.dig[player - 1], self.anti[player - 1]]: return player return 0