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:
- A move is guaranteed to be valid and is placed on an empty block.
- Once a winning condition is reached, no more moves is allowed.
- A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game.
Example:
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);
*/