友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

794. 有效的井字游戏

给你一个字符串数组 board 表示井字游戏的棋盘。当且仅当在井字游戏过程中,棋盘有可能达到 board 所显示的状态时,才返回 true

井字游戏的棋盘是一个 3 x 3 数组,由字符 ' ''X''O' 组成。字符 ' ' 代表一个空位。

以下是井字游戏的规则:

  • 玩家轮流将字符放入空位(' ')中。

  • 玩家 1 总是放字符 'X' ,而玩家 2 总是放字符 'O'

  • 'X''O' 只允许放置在空位中,不允许对已放有字符的位置进行填充。

  • 当有 3 个相同(且非空)的字符填充任何行、列或对角线时,游戏结束。

  • 当所有位置非空时,也算为游戏结束。

  • 如果游戏结束,玩家不允许再放置字符。

示例 1:

0794 01
输入:board = ["O  ","   ","   "]
输出:false
解释:玩家 1 总是放字符 "X" 。

示例 2:

0794 02
输入:board = ["XOX"," X ","   "]
输出:false
解释:玩家应该轮流放字符。

示例 3:

0794 03
输入:board = ["XOX","O O","XOX"]
输出:true

提示:

  • board.length == 3

  • board[i].length == 3

  • board[i][j]'X''O'' '

思路分析

  • 一刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-05-07 21:52:04
 */
public boolean validTicTacToe(String[] board) {
  int length = board.length;
  char[][] grid = new char[length][length];
  int xc = 0, oc = 0;
  boolean xRowOver = false;
  boolean oRowOver = false;
  for (int row = 0; row < length; row++) {
    char[] chars = board[row].toCharArray();
    int ixc = 0;
    int ioc = 0;
    for (int column = 0; column < chars.length; column++) {
      char c = chars[column];
      if (c == 'X') {
        xc++;
        ixc++;
      } else if (c == 'O') {
        oc++;
        ioc++;
      }
      grid[row][column] = c;
    }
    if (!xRowOver && ixc == 3) {
      xRowOver = true;
    }
    if (!oRowOver && ioc == 3) {
      oRowOver = true;
    }
  }
  // X 必须比 O 多,但是最多能多一个
  // O 不会比 X 多
  if (xc - oc > 1 || oc - xc >= 1) {
    return false;
  }
  boolean xColOver = false;
  boolean oColOver = false;
  for (int i = 0; i < length; i++) {
    xColOver = grid[0][i] == 'X' && grid[1][i] == 'X' && grid[2][i] == 'X';
    oColOver = grid[0][i] == 'O' && grid[1][i] == 'O' && grid[2][i] == 'O';
    if (xColOver || oColOver) {
      break;
    }
  }
  boolean xDiagOver = (grid[0][0] == 'X' && grid[1][1] == 'X' && grid[2][2] == 'X')
    || (grid[0][2] == 'X' && grid[1][1] == 'X' && grid[2][0] == 'X');
  boolean oDiagOver = (grid[0][0] == 'O' && grid[1][1] == 'O' && grid[2][2] == 'O')
    || (grid[0][2] == 'O' && grid[1][1] == 'O' && grid[2][0] == 'O');
  // 如果 X 获胜,则 X 比 O 多一个
  if ((xRowOver || xColOver || xDiagOver) && xc - oc != 1) {
    return false;
  }
  // 如果 O 获胜,则 X 与 O 个数相等
  if ((oRowOver || oColOver || oDiagOver) && xc != oc) {
    return false;
  }
  return true;
}

参考资料