2019-04-04 12:50:57 +0000   |     algorithm leetcode string array   |   Viewed times   |    

题目

A Tic-Tac-Toe board is given 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, and consists of characters “ “, “X”, and “O”. The “ “ character represents an empty square.

Here are the rules of Tic-Tac-Toe:

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 = ["XXX", "   ", "OOO"]
Output: false

Example 4:

Input: board = ["XOX", "O O", "XOX"]
Output: true

Note:

一次遍历

首先逻辑是这样:

  1. X因为先行,数量要么和O相等,要么比O多一个
  2. 如果X赢了,那么X的数量必须比O多一个(因为最后一步是X走)
  3. 如果O赢了,那么O的数量和X必须相等(因为最后一步是O走)
  4. XO不可能同时赢(因为一方获胜,游戏终止)

一次遍历的做法,需要额外空间统计每一列,以及斜向的XO的数量。int[3][2] columnCount统计每一列,int[2][2] diagonalCount统计斜向。

代码

下面代码是系统性地处理问题,如果board扩展到4*4或者n*n同样适用。如果觉得题目规定了3*3,直接放到char[9]里检查,也行。

class Solution {
    public boolean validTicTacToe(String[] board) {
        boolean xWin = false, oWin = false;
        int[][] columnCount = new int[3][2];
        int[][] diagonalCount = new int[2][2];
        int xCount = 0, oCount = 0;
        for (int i = 0; i < 3; i++) {
            String row = board[i];
            if (row.equals("XXX")) {
                xWin = true;
            } else if (row.equals("OOO")) {
                oWin = true;
            }
            for (int j = 0; j < 3; j++) {
                char c = row.charAt(j);
                if (c == 'X') {
                    xCount++;
                    columnCount[j][0]++;
                    if (i == j) diagonalCount[0][0]++;
                    if ((i + j) == 2) diagonalCount[1][0]++;
                } else if (c == 'O') {
                    oCount++;
                    columnCount[j][1]++;
                    if (i == j) diagonalCount[0][1]++;
                    if ((i + j) == 2) diagonalCount[1][1]++;
                }
            }
        }
        for (int i = 0; i < 3; i++) {
            if (columnCount[i][0] == 3) xWin = true;
            if (columnCount[i][1] == 3) oWin = true;
        }
        for (int i = 0; i < 2; i++) {
            if (diagonalCount[i][0] == 3) xWin = true;
            if (diagonalCount[i][1] == 3) oWin = true;
        }
        if (xWin && oWin) return false;
        if (xCount < oCount || (xCount - oCount) > 1) return false;
        if (xWin && xCount == oCount) return false;
        if (oWin && (xCount - oCount) == 1) return false;
        return true;
    }
}

结果

valid-tic-tac-toe-state-1