1、由于 X 先手,O 后手,两者轮流下子。因此 O 的数量不会超过 X,且两者数量差不会超过 11,否则为无效局面; 2、若局面是 X 获胜,导致该局面的最后一个子必然是 X,此时必然有 X 数量大于 O(X 为先手),否则为无效局面; 3、若局面是 O 获胜,导致该局面的最后一个子必然是 O,此时必然有 X 数量等于 O(X 为先手),否则为无效局面; 4、局面中不可能出现两者同时赢(其中一方赢后,游戏结束)。
以上4种均为False,检测完毕后其余情况为True
class Solution:
def validTicTacToe(self, board) -> bool:
x, o = 0, 0
#统计X和O的个数
for i in range(3):
for j in range(3):
c = board[i][j]
if c == 'X':
x += 1
elif c == 'O':
o += 1
# 辅助函数,判断某行或某列或对角线有无三连相同
def check(c):
for i in range(3):
# 某行相同
if board[i][0] == c and board[i][1] == c and board[i][2] == c:
return True
# 某列相同
if board[0][i] == c and board[1][i] == c and board[2][i] == c :
return True
a = True
b = True
for i in range(3):
for j in range(3):
if i == j:
a &= (board[i][j] == c) #检测主对角线是否相同
if i + j == 2:
b &= (board[i][j] == c) #检测副对角线是否相同
return a or b
# 检测X和O是否连成线
a = check('X')
b = check('O')
# 分情况讨论
if o > x or x - o > 1:
return False
if a and x <= o: # 若X获胜
return False
if b and x != o: # 若O获胜
return False
if a and b:
return False
return True #其余情况true