1. Optimized Brute Force

class TicTacToe:
    def __init__(self, n: int):
        self.board = [[0] * n for _ in range(n)]
        self.n = n
    
    def move(self, row: int, col: int, player: int) -> int:
        self.board[row][col] = player
        
        # check if the player wins
        if ((self._check_row(row, player)) or
            (self._check_column(col, player)) or
            (row == col and self._check_diagonal(player)) or
            (col == self.n - row - 1 and self._check_anti_diagonal(player))):
            return player
        
        # No one wins
        return 0
    
    def _check_diagonal(self, player: int) -> bool:
        for row in range(self.n):
            if self.board[row][row] != player:
                return False
        return True
    
    def _check_anti_diagonal(self, player: int) -> bool:
        for row in range(self.n):
            if self.board[row][self.n - row - 1] != player:
                return False
        return True
    
    def _check_column(self, col: int, player: int) -> bool:
        for row in range(self.n):
            if self.board[row][col] != player:
                return False
        return True
    
    def _check_row(self, row: int, player: int) -> bool:
        for col in range(self.n):
            if self.board[row][col] != player:
                return False
        return True

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(n2)O(n^2)

Where nn is the size of the Tic-Tac-Toe board.


2. Optimized Approach

class TicTacToe:
    
    def __init__(self, n: int):
        self.rows = [0] * n
        self.cols = [0] * n
        self.diagonal = 0
        self.antiDiagonal = 0

    def move(self, row: int, col: int, player: int) -> int:
        currentPlayer = 1 if player == 1 else -1
        
        # update currentPlayer in rows and cols arrays
        self.rows[row] += currentPlayer
        self.cols[col] += currentPlayer
        
        # update diagonal
        if row == col:
            self.diagonal += currentPlayer
        
        # update anti diagonal
        if col == (len(self.cols) - row - 1):
            self.antiDiagonal += currentPlayer
        
        n = len(self.rows)
        
        # check if the current player wins
        if (abs(self.rows[row]) == n or
            abs(self.cols[col]) == n or
            abs(self.diagonal) == n or
            abs(self.antiDiagonal) == n):
            return player
        
        # No one wins
        return 0

Time & Space Complexity

  • Time complexity: O(1)O(1)
  • Space complexity: O(n)O(n)

Where nn is the size of the Tic-Tac-Toe board.