LC 794. 有效的井字游戏

题目描述

这是 LeetCode 上的 794. 有效的井字游戏 ,难度为 中等

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

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

以下是井字游戏的规则:

  • 玩家轮流将字符放入空位(' ')中。
  • 玩家 $1$ 总是放字符 'X' ,而玩家 $2$ 总是放字符 'O'
  • ‘X’ 和 ‘O’ 只允许放置在空位中,不允许对已放有字符的位置进行填充。
  • 当有 $3$ 个相同(且非空)的字符填充任何行、列或对角线时,游戏结束。
  • 当所有位置非空时,也算为游戏结束。
  • 如果游戏结束,玩家不允许再放置字符。

示例 1:

1
2
3
4
5
输入:board = ["O  ","   ","   "]

输出:false

解释:玩家 1 总是放字符 "X"

示例 2:

1
2
3
4
5
输入:board = ["XOX"," X ","   "]

输出:false

解释:玩家应该轮流放字符。

示例 3:

1
2
3
输入:board = ["XXX","   ","OOO"]

输出:false

示例 4:

1
2
3
输入:board = ["XOX","O O","XOX"]

输出:true

提示:

  • board.length == 3
  • board[i].length == 3
  • board[i][j]'X''O'' '

分情况讨论

给定的棋盘大小固定,对于无效情况进行分情况讨论即可:

  1. 由于 X 先手,O 后手,两者轮流下子。因此 O 的数量不会超过 X,且两者数量差不会超过 $1$,否则为无效局面;
  2. 若局面是 X 获胜,导致该局面的最后一个子必然是 X,此时必然有 X 数量大于 OX 为先手),否则为无效局面;
  3. 若局面是 O 获胜,导致该局面的最后一个子必然是 O,此时必然有 X 数量等于 OX 为先手),否则为无效局面;
  4. 局面中不可能出现两者同时赢(其中一方赢后,游戏结束)。

代码:

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
class Solution {
public boolean validTicTacToe(String[] board) {
char[][] cs = new char[3][3];
int x = 0, o = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
char c = board[i].charAt(j);
if (c == 'X') x++;
else if (c == 'O') o++;
cs[i][j] = c;
}
}
boolean a = check(cs, 'X'), b = check(cs, 'O');
if (o > x || x - o > 1) return false;
if (a && x <= o) return false;
if (b && o != x) return false;
if (a && b) return false;
return true;
}
boolean check(char[][] cs, char c) {
for (int i = 0; i < 3; i++) {
if (cs[i][0] == c && cs[i][1] == c && cs[i][2] == c) return true;
if (cs[0][i] == c && cs[1][i] == c && cs[2][i] == c) return true;
}
boolean a = true, b = true;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == j) a &= cs[i][j] == c;
if (i + j == 2) b &= cs[i][j] == c;
}
}
return a || b;
}
}

  • 时间复杂度:棋盘大小固定,遍历棋盘次数为常数。复杂度为 $O(C)$
  • 空间复杂度:使用了 $char$ 二维数组对 $board$ 进行转存,复杂度为 $O(C)$;全程使用 charAt 的话复杂度为 $O(1)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.794 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!