边工作边刷题:70天一遍leetcode: day 95-2

Design Tic-Tac-Toe

要点:这题和design题接近,重点是如何表示,从而便于计算game状态。巧妙的方法是只用list[i]表示某行/列,两个players分别从+/-两个方向累加,哪个位置累加到n/-n则代表哪个player胜出。当然还有对角线/反对角线的情况

  • 和8-queen,sudoku的区别?
    • 首先这题的目标是count,而8-queen/sudoku是occurrence。所以每个行/列都要用一个元素表示count,所以最终是2个list。8-queen只有列需要用list,相当于是inverse的:记录了每列的占用情况。而sudoku是某个数(val)在某行/列是否已经用过,所以是2d boolean数组。
    • 斜向只有对角线和反对角线的格子数和行列是相同的,所以只有2个变量表示

https://repl.it/Catg/1

# 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?

# Hint:

# Could you trade extra space such that move() operation can be done in O(1)?
# You need two arrays: int rows[n], int cols[n], plus two variables: diagonal, anti_diagonal.

class TicTacToe(object):

    def __init__(self, n):
        """
        Initialize your data structure here.
        :type n: int
        """
        self._n = n
        self._rowcount = [0]*n
        self._colcount = [0]*n
        self._diag = 0
        self._rdiag = 0

    def move(self, row, col, player):
        """
        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.
        :type row: int
        :type col: int
        :type player: int
        :rtype: int
        """
        add = 1 if player==1 else -1
        self._rowcount[row]+=add
        self._colcount[col]+=add
        if row==col:
            self._diag+=add
        
        if row==self._n-1-col:
            self._rdiag+=add
        
        if self._diag==self._n*add or self._rdiag==self._n*add or \
            self._rowcount[row]==self._n*add or self._colcount[col]==self._n*add:
                return player
        return 0

# Your TicTacToe object will be instantiated and called as such:
# obj = TicTacToe(n)
# param_1 = obj.move(row,col,player)

posted @ 2016-07-11 20:27  absolute100  阅读(145)  评论(0编辑  收藏  举报