有效的井字游戏

难度:中等

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

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

以下是井字游戏的规则:

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

示例 1:

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

示例 2:

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

示例 3:

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

分类讨论

思路:
题目要求判断当前游戏板是否生效,我们思考游戏板生效的规则:

  • 玩家轮流将字符放入空位 " " \texttt{" "} " " 中。第一个玩家总是放字符 "X" \texttt{"X"} "X",且第二个玩家总是放字符 "O" \texttt{"O"} "O"。因为第一个玩家总是先手,这就要求游戏板中字符 "X" \texttt{"X"} "X" 的数量一定是大于等于字符 "O" \texttt{"O"} "O" 的数量。
  • "X" \texttt{"X"} "X" 和 "O" \texttt{"O"} "O" 只允许放置在空位中,不允许对已放有字符的位置进行填充。
  • 当有 3 3 3 个相同(且非空)的字符填充任何行、列或对角线时,游戏结束。当所有位置非空时,也算为游戏结束。如果游戏结束,玩家不允许再放置字符,不可能能出现二者同时获胜的情况,因此游戏板上不可能同时出现 3 3 3 个 "X" \texttt{"X"} "X" 在一行和 3 3 3 个 "O" \texttt{"O"} "O" 在另一行。
  • 获胜的玩家一定是在自己放棋后赢得比赛,赢得比赛后,立马停止放置字符。
    • 如果第一个玩家获胜,由于第一个玩家是先手,则次数游戏板中 "X" \texttt{"X"} "X" 的数量比 "O" \texttt{"O"} "O" 的数量多 1 1 1。
    • 如果第二个玩家获胜,则 "X" \texttt{"X"} "X" 的数量与 "O" \texttt{"O"} "O" 的数量相同。

以上条件包含了游戏板生效的全部情况,可以通过反证法验证上面分类条件的正确性。在合法的游戏板,只能有 3 3 3 种结果合法,要么没有任何玩家赢,要么玩家一赢,要么玩家二赢。我们可以通过检查两种棋的数量关系即可验证是否有效,同时我们要检测是否存在两个玩家同时赢这种非法情况。

算法实现细节如下:

  • 首先统计游戏板上 "X" \texttt{"X"} "X" 和 "O" \texttt{"O"} "O" 的数量并记录在 xCount \textit{xCount} xCount 和 oCount \textit{oCount} oCount 中,如果不满足 xCount ≥ oCount \textit{xCount} \ge \textit{oCount} xCount≥oCount,则此时为非法,直接返回 false \texttt{false} false。
  • 然后我们检查是否有玩家是否获胜,我们检查在棋盘的 3 3 3 行, 3 3 3 列和 2 2 2 条对角线上是否有该玩家的连续 3 3 3 枚棋子。我们首先检测玩家一是否获胜,如果玩家一获胜,则检查 xCount \textit{xCount} xCount 是否等于 oCount + 1 \textit{oCount} + 1 oCount+1;我们继续检测玩家二是否获胜,如果玩家二获胜,则检查 xCount \textit{xCount} xCount 是否等于 oCount \textit{oCount} oCount。
  • 对于特殊情况如果两个玩家都获胜,是否可以检测出该非法情况?如果同时满足两个玩家都获胜,则 "X" \texttt{"X"} "X" 和 "O" \texttt{"O"} "O" 数量的合法的组合可能为 ( 3 , 3 ) , ( 4 , 3 ) , ( 4 , 4 ) , ( 5 , 4 ) (3,3),(4,3),(4,4),(5,4) (3,3),(4,3),(4,4),(5,4),对于 ( 3 , 3 ) , ( 4 , 4 ) (3,3),(4,4) (3,3),(4,4) 不满足玩家一获胜的检测条件,对于 ( 4 , 3 ) , ( 5 , 4 ) (4,3),(5,4) (4,3),(5,4) 满足玩家一获胜的检测条件但不满足玩家二的获胜条件。

时间复杂度: O ( C ) O(C) O(C),由于此题给定的棋盘大小为常数 C = 9 C=9 C=9,因此时间复杂度为常数。
空间复杂度: O ( 1 ) O(1) O(1)。

class Solution:def win(self, char, board):return any(board[0][i] == char and board[1][i] == char and board[2][i] == char orboard[i][0] == char and board[i][1] == char and board[i][2] == char for i in range(3)) or \board[0][0] == char and board[1][1] == char and board[2][2] == char or \board[2][0] == char and board[1][1] == char and board[0][2] == chardef validTicTacToe(self, board: List[str]) -> bool:ocount = sum(row.count("O") for row in board)xcount = sum(row.count("X") for row in board)return not (xcount - ocount not in [0, 1] orxcount - ocount != 0 and self.win('O', board) orxcount - ocount != 1 and self.win('X', board))

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-tic-tac-toe-state

算法刷题打卡第34天:有效的井字游戏相关推荐

  1. 算法刷题打卡第63天:对称二叉树

    对称二叉树 难度:简单 给你一个二叉树的根节点 root , 检查它是否轴对称. 示例 1: 输入:root = [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root = [1, ...

  2. 算法刷题打卡第43天:Dota2 参议院

    Dota2 参议院 难度:中等 Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成.现在参议院希望对一个 Dota2 游戏里的改变作出 ...

  3. 算法刷题打卡第76天:判断矩阵是否是一个 X 矩阵

    判断矩阵是否是一个 X 矩阵 难度:简单 如果一个正方形矩阵满足下述 全部 条件,则称之为一个 X 矩阵 : 矩阵对角线上的所有元素都 不是 0 矩阵中所有其他元素都是 0 给你一个大小为 n x n ...

  4. 算法刷题打卡第70天:强密码检验器 II

    强密码检验器 II 难度:简单 如果一个密码满足以下所有条件,我们称它是一个 强 密码: 它有至少 8 个字符. 至少包含 一个小写英文 字母. 至少包含 一个大写英文 字母. 至少包含 一个数字 . ...

  5. 算法刷题打卡第11天:合并两个有序数组

    合并两个有序数组 难度:简单 给你两个按非递减顺序排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目. 请你合并 nums2 到 ...

  6. 算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)

    文章目录 acwing869. 试除法求约数 acwing870. 约数个数 acwing871. 约数之和 acwing872. 最大公约数 acwing869. 试除法求约数 acwing869. ...

  7. 找到所有数组中消失的数字_【一点资讯】千万程序员的呼声:面试如何拿到大厂Offer?这份阅读量超过11W+的算法刷题宝典请你原地查收 www.yidianzixun.com...

    如何才能通过面试拿到大厂Offer? "刷leetcode!" 这是我听到最多的回答! 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是面测试.算 ...

  8. 力扣 (LeetCode)-对称二叉树,树|刷题打卡

    Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者 [已开启]任务一:刷题打卡 * 10 篇 哪吒人生信条:如果你所学的东西 处于喜欢 ...

  9. 第一届LeetCode刷题打卡赢现金活动开始啦,助力每一位想拿大厂offer的小伙伴!

    大家好,我是路飞!第一届leetcode(剑指Offer.LeetCode Top100)刷题打卡活动即将开始啦 (助力大厂Offer收割机)~ 活动形式: LeetCode刷题在自己的CSDN博客上 ...

最新文章

  1. iMeta:已被谷歌学术(Google Scholar)收录
  2. 上市公司相关财务指标
  3. 几种jvm OOM问题
  4. ajax读取.txt文件出现乱码
  5. 吃鱼可以不挑刺了?华中农业大学发现鳊鱼肌间刺表达基因,可培育“无刺鱼”...
  6. web界面左边菜单设计_前端产品经理难点|“取消按钮”逻辑设计
  7. LeetCode每周刷题(2019.7.1-2019.7.7)
  8. getWriter() has already been called for this response
  9. php 不通过表单post,php – 简单表单不通过_POST发送数据
  10. appium 学习教程
  11. WeChat Subscribers Lite - 微信公众订阅号自动回复WordPress插件
  12. 指数族分布(2):矩母函数、累积量生成函数
  13. 【Python05】Python转义字符
  14. linux 下 cents os 7 下 安装JDK JRE TOMCAT 并配置环境变量
  15. thinkphp3.2读取Excel文件
  16. 怎样在PDF文档中添加插入图片
  17. 循环冗余校验-CRC
  18. linux强制网卡linkup,使用ip link set eth0 up 命令启用网卡后,网络不通的问题的解决...
  19. python之Matplotlib
  20. 软件测试行业的现状和前景

热门文章

  1. ElementUI分页组件+Vue
  2. Android Canvas rotate 和translate 两个方法的研究
  3. Handler消息机制介绍,流程梳理
  4. docker方式运行SRS
  5. abaqus截面惯性矩_Abaqus基本概念汇总
  6. Vue绘制折线图并渲染数据
  7. 计算机主机制造过程,电脑宣传片的制作流程
  8. 安卓-恢复模式--Recovery
  9. 行级标签文本格式化标签
  10. 【分享】优秀外国英文网站