# 348. Design Tic-Tac-Toe

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:

``````Given _n_ = 3, assume that player 1 is "X" and player 2 is "O" in the board.

TicTacToe toe = new TicTacToe(3);

toe.move(0, 0, 1); - > Returns 0 (no one wins)
|X| | |
| | | |    // Player 1 makes a move at (0, 0).
| | | |

toe.move(0, 2, 2); -> Returns 0 (no one wins)
|X| |O|
| | | |    // Player 2 makes a move at (0, 2).
| | | |

toe.move(2, 2, 1); -> Returns 0 (no one wins)
|X| |O|
| | | |    // Player 1 makes a move at (2, 2).
| | |X|

toe.move(1, 1, 2); -> Returns 0 (no one wins)
|X| |O|
| |O| |    // Player 2 makes a move at (1, 1).
| | |X|

toe.move(2, 0, 1); -> Returns 0 (no one wins)
|X| |O|
| |O| |    // Player 1 makes a move at (2, 0).
|X| |X|

toe.move(1, 0, 2); -> Returns 0 (no one wins)
|X| |O|
|O|O| |    // Player 2 makes a move at (1, 0).
|X| |X|

toe.move(2, 1, 1); -> Returns 1 (player 1 wins)
|X| |O|
|O|O| |    // Player 1 makes a move at (2, 1).
|X|X|X|
``````

Could you do better than O( n 2) per `move()`

Hint:

Could you trade extra space such that move() operation can be done in O(1)?
You need two arrays: int rows[n], int cols[n], plus two variables: diagonal, anti_diagonal.

CareerCup上的原题，请参见我之前的博客17.2 Tic Tac Toe。我们首先来O(n2)的解法，这种方法的思路很straightforward，就是建立一个nxn大小的board，其中0表示该位置没有棋子，1表示玩家1放的子，2表示玩家2。那么棋盘上每增加一个子，我们都扫描当前行列，对角线，和逆对角线，看看是否有三子相连的情况，有的话则返回对应的玩家，没有则返回0，参见代码如下：

``````class TicTacToe {
public:
/** Initialize your data structure here. */
TicTacToe(int n) {
board.resize(n, vector<int>(n, 0));
}

int move(int row, int col, int player) {
board[row][col] = player;
int i = 0, j = 0, n = board.size();
for (j = 1; j < n; ++j) {
if (board[row][j] != board[row][j - 1]) break;
}
if (j == n) return player;
for (i = 1; i < n; ++i) {
if (board[i][col] != board[i - 1][col]) break;
}
if (i == n) return player;
if (row == col) {
for (i = 1; i < n; ++i) {
if (board[i][i] != board[i - 1][i - 1]) break;
}
if (i == n) return player;
}
if (row + col == n - 1) {
for (i = 1; i < n; ++i) {
if (board[n - i - 1][i] != board[n - i][i - 1]) break;
}
if (i == n) return player;
}
return 0;
}

private:
vector<vector<int>> board;
};
``````

``````class TicTacToe {
public:
/** Initialize your data structure here. */
TicTacToe(int n): rows(n), cols(n), N(n), diag(0), rev_diag(0) {}

int move(int row, int col, int player) {
int add = player == 1 ? 1 : -1;
diag += (row == col ? add : 0);
rev_diag += (row == N - col - 1 ? add : 0);
return (abs(rows[row]) == N || abs(cols[col]) == N || abs(diag) == N || abs(rev_diag) == N) ? player : 0;
}

private:
vector<int> rows, cols;
int diag, rev_diag, N;
};
``````

https://leetcode.com/problems/design-tic-tac-toe/

https://discuss.leetcode.com/topic/44548/java-o-1-solution-easy-to-understand

https://discuss.leetcode.com/topic/44605/c-time-o-1-space-o-n-short-simple-solution

 微信打赏 Venmo 打赏
（欢迎加入博主的知识星球，博主将及时答疑解惑，并分享刷题经验与总结，试运营期间前五十位可享受半价优惠～）

×

Help us with donation