Given a Tic-Tac-Toe board as a string array board
, return true
if and only if it is possible to reach this board position during the course of a valid tic-tac-toe game.
The board is a 3 x 3
array that consists of characters ' '
, 'X'
, and 'O'
. The ' '
character represents an empty square.
Here are the rules of Tic-Tac-Toe:
' '
.'X'
characters, while the second player always places 'O'
characters.'X'
and 'O'
characters are always placed into empty squares, never filled ones.
Example 1:
Input: board = ["O "," "," "] Output: false Explanation: The first player always plays "X".
Example 2:
Input: board = ["XOX"," X "," "] Output: false Explanation: Players take turns making moves.
Example 3:
Input: board = ["XOX","O O","XOX"] Output: true
Constraints:
board.length == 3
board[i].length == 3
board[i][j]
is either 'X'
, 'O'
, or ' '
.This problem asks to determine if a given Tic-Tac-Toe board represents a valid state reachable during a game. The solution leverages several key observations about the game's rules to efficiently check validity.
Key Observations:
X always goes first: The number of 'X's can be at most one more than the number of 'O's.
Winning condition: If either 'X' or 'O' has won, the game is over. A player can only win if they have made at least three moves.
Impossible states: If 'O' has won and the number of 'O's equals the number of 'X's, the board is invalid. Similarly, if 'X' has won and the number of 'X's is equal to the number of 'O's, or there's one less 'X' than 'O's, the board is invalid.
Algorithm:
Count X's and O's: Count the number of 'X' and 'O' characters on the board.
Check for win conditions: A helper function win(player)
checks if the given player ('X' or 'O') has three in a row (horizontally, vertically, or diagonally).
Validate the counts: The code then checks if the counts of 'X' and 'O' satisfy the rule that the number of 'X's is either equal to or one greater than the number of 'O's.
Check impossible winning scenarios: It then checks if a winning condition exists for 'X' or 'O' and if that winning condition is consistent with the number of X's and O's on the board. This eliminates impossible winning scenarios like 'O' winning when the number of 'O's is less than the number of 'X's or vice-versa.
Time Complexity: O(1) - The algorithm iterates through a fixed-size 3x3 board, so the time taken remains constant regardless of input size.
Space Complexity: O(1) - The algorithm uses a constant amount of extra space to store the counts of 'X' and 'O' and other variables.
class Solution:
def validTicTacToe(self, board: List[str]) -> bool:
def win(x):
for i in range(3):
if all(board[i][j] == x for j in range(3)):
return True
if all(board[j][i] == x for j in range(3)):
return True
if all(board[i][i] == x for i in range(3)):
return True
return all(board[i][2 - i] == x for i in range(3))
x = sum(board[i][j] == 'X' for i in range(3) for j in range(3))
o = sum(board[i][j] == 'O' for i in range(3) for j in range(3))
if x != o and x - 1 != o:
return False
if win('X') and x - 1 != o:
return False
return not (win('O') and x != o)
The Python code directly implements the algorithm described above. The win
function efficiently checks for winning conditions. The main part of the code counts 'X' and 'O', then performs the validity checks based on the rules.
The other languages (Java, C++, Go, JavaScript) follow a similar logic and structure, adapting the syntax and data structures specific to each language. The core algorithm remains unchanged across all implementations.