【我也想刷穿 LeetCode】794. 有效的井字游戏

166 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。

因此每天刷刷LeetCode非常有必要

在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 LeetCode

一、题目描述

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

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

以下是井字游戏的规则:

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

二、思路分析

在第一个下X的条件下会有两种情况: 1.cntO === cntX 如果是O和X的数量相等,那么最后下的O可能会赢 2.cntO === cntX - 1 如果X的数量比O多1,那么最后下的X可能会赢

这里可以用逆向思维去判断,不是最后下的不会赢 假设在情况1下 那么只需遍历两对角线 + 三行 + 三列赢的字符不是X即可 情况2同理

三、代码实现

var validTicTacToe = function (board) {
    const cnt = { O: 0, X: 0 };
    for (const line of board) {
        for (const xo of line) {
            if (xo !== ' ') cnt[xo]++;
        }
    }
    // 不符合两种情况
    if (cnt.O !== cnt.X && cnt.X - cnt.O !== 1) return false;
    // 获取不会赢的字符
    const will_not_win = cnt.X > cnt.O ? 'O' : 'X';
    // 两对角线
    if (board[0][0] === will_not_win && board[0][0] === board[1][1] && board[0][0] === board[2][2]) return false;
    if (board[0][2] === will_not_win && board[0][2] === board[1][1] && board[0][2] === board[2][0]) return false;
    for (let i = 0; i < 3; i++) {
        // 三行
        if (board[i][0] === will_not_win && board[i][0] === board[i][1] && board[i][0] === board[i][2]) return false;
        // 三列
        if (board[0][i] === will_not_win && board[0][i] === board[1][i] && board[0][i] === board[2][i]) return false;
    }
    return true;
};

四、总结

以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~