60
60
61
61
<!-- 这里可写通用的实现逻辑 -->
62
62
63
+ ** 方法一:分类讨论**
64
+
65
+ 我们先统计当前棋盘上 ` 'X' ` 和 ` 'O' ` 的数量,记为 $x$ 和 $o$。接下来,我们分情况讨论:
66
+
67
+ - 如果 $x \neq o$ 且 $x - 1 \neq o$,则当前棋盘不可能是有效棋盘,返回 ` false ` 。
68
+ - 如果当前棋盘上玩家 1 获胜,但 $x-1 \neq o$,则当前棋盘不可能是有效棋盘,返回 ` false ` 。
69
+ - 如果当前棋盘上玩家 2 获胜,但 $x \neq o$,则当前棋盘不可能是有效棋盘,返回 ` false ` 。
70
+ - 其他情况下,当前棋盘是有效棋盘,返回 ` true ` 。
71
+
72
+ 时间复杂度 $O(C)$,空间复杂度 $O(1)$。其中 $C$ 是棋盘上的格子数。本题中 $C = 9$。
73
+
63
74
<!-- tabs:start -->
64
75
65
76
### ** Python3**
69
80
``` python
70
81
class Solution :
71
82
def validTicTacToe (self , board : List[str ]) -> bool :
72
- def win (p ):
83
+ def win (x ):
73
84
for i in range (3 ):
74
- if board[i][0 ] == board[i][ 1 ] == board[i][ 2 ] == p :
85
+ if all ( board[i][j ] == x for j in range ( 3 )) :
75
86
return True
76
- if board[0 ][i] == board[ 1 ][i] == board[ 2 ][i] == p :
87
+ if all ( board[j ][i] == x for j in range ( 3 )) :
77
88
return True
78
- if board[0 ][ 0 ] == board[ 1 ][ 1 ] == board[ 2 ][ 2 ] == p :
89
+ if all ( board[i][i ] == x for i in range ( 3 )) :
79
90
return True
80
- return board[0 ][2 ] == board[1 ][1 ] == board[2 ][0 ] == p
81
-
82
- x, o = 0 , 0
83
- for i in range (3 ):
84
- for j in range (3 ):
85
- if board[i][j] == ' X' :
86
- x += 1
87
- elif board[i][j] == ' O' :
88
- o += 1
91
+ return all (board[i][2 - i] == x for i in range (3 ))
89
92
93
+ x = sum (board[i][j] == ' X' for i in range (3 ) for j in range (3 ))
94
+ o = sum (board[i][j] == ' O' for i in range (3 ) for j in range (3 ))
90
95
if x != o and x - 1 != o:
91
96
return False
92
-
93
97
if win(' X' ) and x - 1 != o:
94
98
return False
95
-
96
99
return not (win(' O' ) and x != o)
97
100
```
98
101
@@ -102,121 +105,153 @@ class Solution:
102
105
103
106
``` java
104
107
class Solution {
108
+ private String [] board;
109
+
105
110
public boolean validTicTacToe (String [] board ) {
106
- int x = 0 , o = 0 ;
107
- for (int i = 0 ; i < 3 ; i++ ) {
108
- for (int j = 0 ; j < 3 ; j++ ) {
109
- if (board[i]. charAt(j) == ' X' ) {
110
- x++ ;
111
- } else if (board[i]. charAt(j) == ' O' ) {
112
- o++ ;
113
- }
114
- }
115
- }
111
+ this . board = board;
112
+ int x = count(' X' ), o = count(' O' );
116
113
if (x != o && x - 1 != o) {
117
114
return false ;
118
115
}
119
- if (win(board, ' X' ) && x - 1 != o) {
116
+ if (win(' X' ) && x - 1 != o) {
120
117
return false ;
121
118
}
122
- return ! (win(board, ' O' ) && x != o);
119
+ return ! (win(' O' ) && x != o);
123
120
}
124
121
125
- private boolean win (String [] b , char p ) {
126
- for (int i = 0 ; i < 3 ; i ++ ) {
127
- if (b [i]. charAt(0 ) == p && b [i]. charAt(1 ) == p && b [i]. charAt(2 ) == p ) {
122
+ private boolean win (char x ) {
123
+ for (int i = 0 ; i < 3 ; ++ i ) {
124
+ if (board [i]. charAt(0 ) == x && board [i]. charAt(1 ) == x && board [i]. charAt(2 ) == x ) {
128
125
return true ;
129
126
}
130
- if (b [0 ]. charAt(i) == p && b [1 ]. charAt(i) == p && b [2 ]. charAt(i) == p ) {
127
+ if (board [0 ]. charAt(i) == x && board [1 ]. charAt(i) == x && board [2 ]. charAt(i) == x ) {
131
128
return true ;
132
129
}
133
130
}
134
- if (b [0 ]. charAt(0 ) == p && b [1 ]. charAt(1 ) == p && b [2 ]. charAt(2 ) == p ) {
131
+ if (board [0 ]. charAt(0 ) == x && board [1 ]. charAt(1 ) == x && board [2 ]. charAt(2 ) == x ) {
135
132
return true ;
136
133
}
137
- return b[0 ]. charAt(2 ) == p && b[1 ]. charAt(1 ) == p && b[2 ]. charAt(0 ) == p;
134
+ return board[0 ]. charAt(2 ) == x && board[1 ]. charAt(1 ) == x && board[2 ]. charAt(0 ) == x;
135
+ }
136
+
137
+ private int count (char x ) {
138
+ int cnt = 0 ;
139
+ for (var row : board) {
140
+ for (var c : row. toCharArray()) {
141
+ if (c == x) {
142
+ ++ cnt;
143
+ }
144
+ }
145
+ }
146
+ return cnt;
138
147
}
139
148
}
140
149
```
141
150
151
+ ### ** C++**
152
+
153
+ ``` cpp
154
+ class Solution {
155
+ public:
156
+ bool validTicTacToe(vector<string >& board) {
157
+ auto count = [ &] (char x) {
158
+ int ans = 0;
159
+ for (auto& row : board) for (auto& c : row) ans += c == x;
160
+ return ans;
161
+ };
162
+ auto win = [ &] (char x) {
163
+ for (int i = 0; i < 3; ++i) {
164
+ if (board[ i] [ 0 ] == x && board[ i] [ 1 ] == x && board[ i] [ 2 ] == x) return true;
165
+ if (board[ 0] [ i ] == x && board[ 1] [ i ] == x && board[ 2] [ i ] == x) return true;
166
+ }
167
+ if (board[ 0] [ 0 ] == x && board[ 1] [ 1 ] == x && board[ 2] [ 2 ] == x) return true;
168
+ return board[ 0] [ 2 ] == x && board[ 1] [ 1 ] == x && board[ 2] [ 0 ] == x;
169
+ };
170
+ int x = count('X'), o = count('O');
171
+ if (x != o && x - 1 != o) return false;
172
+ if (win('X') && x - 1 != o) return false;
173
+ return !(win('O') && x != o);
174
+ }
175
+ };
176
+ ```
177
+
142
178
### **Go**
143
179
144
180
```go
145
181
func validTicTacToe(board []string) bool {
146
- x , o := 0 , 0
147
- for i := 0 ; i < 3 ; i++ {
148
- for j := 0 ; j < 3 ; j++ {
149
- if board[i][j] == ' X' {
182
+ var x, o int
183
+ for _, row := range board {
184
+ for _, c := range row {
185
+ if c == 'X' {
150
186
x++
151
- } else if board[i][j] == ' O' {
187
+ } else if c == 'O' {
152
188
o++
153
189
}
154
190
}
155
191
}
156
- if x != o && x-1 != o {
157
- return false
158
- }
159
- if win (board, ' X' ) && x-1 != o {
160
- return false
161
- }
162
- return !(win (board, ' O' ) && x != o)
163
- }
164
-
165
- func win (b []string , p byte ) bool {
166
- for i := 0 ; i < 3 ; i++ {
167
- if b[i][0 ] == p && b[i][1 ] == p && b[i][2 ] == p {
168
- return true
192
+ win := func(x byte) bool {
193
+ for i := 0; i < 3; i++ {
194
+ if board[i][0] == x && board[i][1] == x && board[i][2] == x {
195
+ return true
196
+ }
197
+ if board[0][i] == x && board[1][i] == x && board[2][i] == x {
198
+ return true
199
+ }
169
200
}
170
- if b [0 ][i ] == p && b [1 ][i ] == p && b [2 ][i ] == p {
201
+ if board [0][0 ] == x && board [1][1 ] == x && board [2][2 ] == x {
171
202
return true
172
203
}
204
+ return board[0][2] == x && board[1][1] == x && board[2][0] == x
173
205
}
174
- if b[0 ][0 ] == p && b[1 ][1 ] == p && b[2 ][2 ] == p {
175
- return true
206
+ if x != o && x-1 != o {
207
+ return false
208
+ }
209
+ if win('X') && x-1 != o {
210
+ return false
176
211
}
177
- return b[ 0 ][ 2 ] == p && b[ 1 ][ 1 ] == p && b[ 2 ][ 0 ] == p
212
+ return !(win('O') && x != o)
178
213
}
179
214
```
180
215
181
- ### ** C++**
182
-
183
- ``` cpp
184
- class Solution {
185
- public:
186
- bool validTicTacToe(vector<string >& board) {
187
- int x = 0, o = 0;
188
- for (int i = 0; i < 3; ++i) {
189
- for (int j = 0; j < 3; ++j) {
190
- if (board[ i] [ j ] == 'X') {
191
- ++x;
192
- } else if (board[ i] [ j ] == 'O') {
193
- ++o;
194
- }
216
+ ### ** JavaScript**
217
+
218
+ ``` js
219
+ /**
220
+ * @param {string[]} board
221
+ * @return {boolean}
222
+ */
223
+ var validTicTacToe = function (board ) {
224
+ function count (x ) {
225
+ let cnt = 0 ;
226
+ for (const row of board) {
227
+ for (const c of row) {
228
+ cnt += c == x;
195
229
}
196
230
}
197
- if (x != o && x - 1 != o) {
198
- return false;
199
- }
200
- if (win(board, 'X') && x - 1 != o) {
201
- return false;
202
- }
203
- return !(win(board, 'O') && x != o);
231
+ return cnt;
204
232
}
205
-
206
- bool win(vector<string>& b, char p) {
207
- for (int i = 0; i < 3; ++i) {
208
- if (b[i][0] == p && b[i][1] == p && b[i][2] == p) {
233
+ function win (x ) {
234
+ for (let i = 0 ; i < 3 ; ++ i) {
235
+ if (board[i][0 ] == x && board[i][1 ] == x && board[i][2 ] == x) {
209
236
return true ;
210
237
}
211
- if (b [0 ][i] == p && b [1 ][i] == p && b [2 ][i] == p ) {
238
+ if (board [0 ][i] == x && board [1 ][i] == x && board [2 ][i] == x ) {
212
239
return true ;
213
240
}
214
241
}
215
- if (b [0][0] == p && b [1][1] == p && b [2][2] == p ) {
242
+ if (board [0 ][0 ] == x && board [1 ][1 ] == x && board [2 ][2 ] == x ) {
216
243
return true ;
217
244
}
218
- return b[0][2] == p && b[1][1] == p && b[2][0] == p;
245
+ return board[0 ][2 ] == x && board[1 ][1 ] == x && board[2 ][0 ] == x;
246
+ }
247
+ const [x , o ] = [count (' X' ), count (' O' )];
248
+ if (x != o && x - 1 != o) {
249
+ return false ;
250
+ }
251
+ if (win (' X' ) && x - 1 != o) {
252
+ return false ;
219
253
}
254
+ return ! (win (' O' ) && x != o);
220
255
};
221
256
```
222
257
0 commit comments