1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class TicTacToe {
private int[][] rowCount;
private int[][] colCount;
private int[] diagCount;
private int[] antiDiagCount;
private int size;

public TicTacToe(int n) {
rowCount = new int[n][2];
colCount = new int[n][2];
diagCount = new int[2];
antiDiagCount = new int[2];
size = n;
}

public int move(int row, int col, int player) {
updateCount(row, col, player);
return isWin(row, col, player) ? player : 0;
}

private void updateCount(int row, int col, int player) {
rowCount[row][player - 1] += 1;
colCount[col][player - 1] += 1;
if (row == col) {
diagCount[player - 1] += 1;
}
if (row + col == size - 1) {
antiDiagCount[player - 1] += 1;
}
}

private boolean isWin(int row, int col, int player) {
return rowCount[row][player - 1] == size || colCount[col][player - 1] == size
|| diagCount[player - 1] == size || antiDiagCount[player - 1] == size;
}

}

最直接的想法. 就是记录每一行每一列而且两个对角线player1和player2下的子的个数. 如果在某次move后, 某一行或列或对角线该player的子的数量达到了n, 那么这个player就获胜了.

时间复杂度: O(1)
空间复杂度: O(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class TicTacToe {
private int[] rowCount;
private int[] colCount;
private int diagCount;
private int antiDiagCount;
private int size;

public TicTacToe(int n) {
rowCount = new int[n];
colCount = new int[n];
size = n;
}

public int move(int row, int col, int player) {
updateCount(row, col, player);
return isWin(row, col, player) ? player : 0;
}

private void updateCount(int row, int col, int player) {
int score = player == 1 ? -1 : 1;
rowCount[row] += score;
colCount[col] += score;
if (row == col) {
diagCount += score;
}
if (row + col == size - 1) {
antiDiagCount += score;
}
}

private boolean isWin(int row, int col, int player) {
int targetScore = player == 1 ? -size : size;
return rowCount[row] == targetScore || colCount[col] == targetScore
|| diagCount == targetScore || antiDiagCount == targetScore;
}
}

当然还能把O(n^2)直接降到O(n). 就是如果player1下子, 我们让相应的行列以及对角线(如果影响对角线的话)减去1, player2下子则加1. 那么如果某一行或列或对角线全是player1的子, 则该行或列或对角线的累积值一定是-n, 相应地, 如果是player2在某行某列或者对角线下满的话, 该行或列或对角线的累积值则是n. 这样就把时间复杂度从二次方降到了一次方.

时间复杂度: O(1)
空间复杂度: O(n)