forked from gouthampradhan/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTicTacToe.java
152 lines (132 loc) · 4.29 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package design;
/**
* Created by gouthamvidyapradhan on 13/05/2017.
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:
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|
Follow up:
Could you do better than O(n2) per move() operation?
Solution: The below solution works in O(1) time complexity.
1. For each player move, keep track of count of selection for each row and each column.
2. To keep track of counts in each diagonals we need to first know if the move is made on either one of the diagonals.
The move is made in either of the diagonals if and only if (row = col) AND/OR (col + row = N - 1)
3. As soon as the count in any of column, row or diagonal reach N then return the current player as the winner, else return 0.
*/
public class TicTacToe
{
/**
* Cell class to keep track of first player and second player row/column count
*/
private class Cell
{
int player1 = 0, player2 = 0;
}
Cell[] rows, columns; //Array of row and column cells
private int N, fPD1 = 0, fPD2 = 0, sPD1 = 0, sPD2 = 0; //fPD1 -> first_player_diagonal1
/**
* Main method
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
TicTacToe toe = new TicTacToe(3);
System.out.println(toe.move(0, 0, 1));
System.out.println(toe.move(0, 2, 2));
System.out.println(toe.move(1, 0, 1));
System.out.println(toe.move(1, 1, 2));
System.out.println(toe.move(2, 0, 1));
}
/** Initialize your data structure here. */
public TicTacToe(int n)
{
N = n;
rows = new Cell[N];
columns = new Cell[N];
}
/**
* Move and check who wins.
* @param row row
* @param col col
* @param player player
* @return integer indicating the winner
*/
public int move(int row, int col, int player)
{
switch (player)
{
case 1:
increment(rows, row, 1);
increment(columns, col, 1);
if((col + row) == (N - 1))
fPD2 ++;
if(row == col)
fPD1 ++;
if(rows[row].player1 == N
|| columns[col].player1 == N || fPD1 == N || fPD2 == N)
return 1;
break;
case 2:
increment(rows, row, 2);
increment(columns, col, 2);
if((col + row) == (N - 1))
sPD2 ++;
if(row == col)
sPD1 ++;
if(rows[row].player2 == N
|| columns[col].player2 == N || sPD1 == N || sPD2 == N)
return 2;
break;
}
return 0;
}
/**
* Increment row / col count
* @param cells array of cells
* @param key row / col key
* @param player Player object
*/
private void increment(Cell[] cells, int key, int player) {
Cell p = cells[key];
if(p == null) {
p = new Cell();
cells[key] = p;
}
if(player == 1)
p.player1++;
else p.player2++;
}
}