-
Notifications
You must be signed in to change notification settings - Fork 2
/
TicTacToe.java
121 lines (111 loc) · 3.55 KB
/
TicTacToe.java
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package Leetcode;
/**
* @author kalpak
*
* 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 board n.
* int move(int row, int col, int player) Indicates that player with id player 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 or 2.
* 1 <= row, col <= n
* (row, col) are unique for each different call to move.
* At most n2 calls will be made to move.
*/
public class TicTacToe {
private int[] rows;
private int[] cols;
private int diagonal;
private int antiDiagonal;
/** Initialize your data structure here. */
public TicTacToe(int n) {
// The key observation is that in order to win Tic-Tac-Toe you must have the entire row or column.
// Thus, we don't need to keep track of an entire n^2 board.
// We only need to keep a count for each row and column.
// If at any time a row or column matches the size of the board then that player has won.
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 myPlayer = player == 1 ? 1 : -1;
rows[row] += myPlayer;
cols[col] += myPlayer;
if(row == col)
diagonal += myPlayer;
if(row == rows.length - col - 1)
antiDiagonal += myPlayer;
int size = rows.length;
if(Math.abs(rows[row]) == size || Math.abs(cols[col]) == size || Math.abs(diagonal) == size || Math.abs(antiDiagonal) == size)
return player;
return 0;
}
}