LeetCode-36 - 有效的数独

【中等】力扣算法题解析LeetCode36:有效的数独 本文提出了一种高效验证数独有效性的算法,通过位掩码技术优化空间使用。使用三个整数数组分别记录行、列、3x3宫格内数字出现情况,将每个数字转换为位掩码进行检测。遍历9x9网格时,检查当前数字在位掩码中是否冲突,若无冲突则更新掩码。宫格索引通过(i/3)*3 + j/3计算。该方法仅需27个整数的存储空间,利用位运算实现高效检测,时空复杂度均为O(1)。Java实现代码简洁,通过字符转换、位运算和索引计算快速验证数独有效性。 阅读详情

题目

来源:LeetCode.

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

注意:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 ‘.’ 表示。

示例 1:
在这里插入图片描述

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

  • b o a r d . l e n g t h = = 9 board.length == 9 board.length==9
  • b o a r d [ i ] . l e n g t h = = 9 board[i].length == 9 board[i].length==9
  • b o a r d [ i ] [ j ] 是 一 位 数 字 ( 1 − 9 ) 或 者 ′ . ′ board[i][j] 是一位数字(1-9)或者 '.' board[i][j]是一位数字(1−9)或者′.′

接下来看一下解题思路:

思路一:一次遍历:

    有效的数独满足以下三个条件:

  • 同一个数字在每一行只能出现一次;
  • 同一个数字在每一列只能出现一次;
  • 同一个数字在每一个小九宫格只能出现一次。

    可以使用数组,以数字为下标,出现的次数为值,记录 每一行、每一列 和 每一个小九宫格中,每个数字出现的次数。只需要遍历数独一次,在遍历的过程中更新数组中的计数,并判断是否满足有效的数独的条件即可。

    对于数独的第 i i i 行第 j j j 列的单元格,其中 0 ≤ i , j < 9 0 \le i, j < 9 0≤i,j<9 ,该单元格所在的行下标和列下标分别为 i i i 和 j j j,该单元格所在的小九宫格的行数和列数分别为 ⌊ i 3 ⌋ \Big\lfloor \dfrac{i}{3} \Big\rfloor ⌊3i​⌋ 和 ⌊ j 3 ⌋ \Big\lfloor \dfrac{j}{3} \Big\rfloor ⌊3j​⌋,其中 0 ≤ ⌊ i 3 ⌋ , ⌊ j 3 ⌋ < 3 0 \le \Big\lfloor \dfrac{i}{3} \Big\rfloor, \Big\lfloor \dfrac{j}{3} \Big\rfloor < 3 0≤⌊3i​⌋,⌊3j​⌋<3。

    具体做法是,创建二维数组 rows \textit{rows} rows 和 columns \textit{columns} columns 分别记录数独的每一行和每一列中的每个数字的出现次数,创建三维数组 subboxes \textit{subboxes} subboxes 记录数独的每一个小九宫格中的每个数字的出现次数,其中 rows [ i ] [ index ] \textit{rows}[i][\textit{index}] rows[i][index]、 columns [ j ] [ index ] \textit{columns}[j][\textit{index}] columns[j][index] 和 subboxes [ ⌊ i 3 ⌋ ] [ ⌊ j 3 ⌋ ] [ index ] \textit{subboxes}\Big[\Big\lfloor \dfrac{i}{3} \Big\rfloor\Big]\Big[\Big\lfloor \dfrac{j}{3} \Big\rfloor\Big]\Big[\textit{index}\Big] subboxes[⌊3i​⌋][⌊3j​⌋][index] 分别表示数独的第 i i i 行第 j j j 列的单元格所在的行、列和小九宫格中,数字$ \textit{index} + 1$ 出现的次数,其中 0 ≤ index < 9 0 \le \textit{index} < 9 0≤index<9,对应的数字 index + 1 \textit{index} + 1 index+1 满足 1 ≤ index + 1 ≤ 9 1 \le \textit{index} + 1 \le 9 1≤index+1≤9。

    如果 board [ i ] [ j ] \textit{board}[i][j] board[i][j] 填入了数字 n n n,则将 rows [ i ] [ n − 1 ] \textit{rows}[i][n - 1] rows[i][n−1]、 columns [ j ] [ n − 1 ] \textit{columns}[j][n - 1] columns[j][n−1] 和 subboxes [ ⌊ i 3 ⌋ ] [ ⌊ j 3 ⌋ ] [ n − 1 ] \textit{subboxes}\Big[\Big\lfloor \dfrac{i}{3} \Big\rfloor\Big]\Big[\Big\lfloor \dfrac{j}{3} \Big\rfloor\Big]\Big[n - 1\Big] subboxes[⌊3i​⌋][⌊3j​⌋][n−1] 各加 1 1 1。如果更新后的计数大于 1 1 1,则不符合有效的数独的条件,返回 false \text{false} false。

    如果遍历结束之后没有出现计数大于 1 1 1 的情况,则符合有效的数独的条件,返回 true \text{true} true。
java实现

class Solution {
    public boolean isValidSudoku(char[][] board) {
        int row = board.length;
        int col = board[0].length;

        int[][] rows = new int[row][col];
        int[][] cols = new int[row][col];
        int[][][] sub = new int[3][3][col];

        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                char c = board[i][j];
                if (c != '.') {
                    int index = c - '0' - 1;
                    rows[i][index] += 1;
                    cols[index][j] += 1;
                    sub[i / 3][j / 3][index] += 1;
                    if (rows[i][index] > 1 || cols[index][j] > 1 || sub[i / 3][j / 3][index] > 1) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

C++实现

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int row = board.size();
        int col =  board.size();

        int rows[row][col];
        int cols[row][col];
        int subs[3][3][row];

        memset(rows,0,sizeof(rows));
        memset(cols,0,sizeof(cols));
        memset(subs,0,sizeof(subs));

        for(int i = 0; i < row; ++i) {
            for(int j = 0; j < col; ++j){
                char c = board[i][j];
                if(c != '.') {
                    int index = c - '0' - 1;
                    rows[i][index]++;
                    cols[index][j]++;
                    subs[i/3][j/3][index]++;
                    if(rows[i][index] > 1 || cols[index][j] > 1 || subs[i/3][j/3][index] > 1) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
};

python实现

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        rows = [[0] * 9 for _ in range(9)]
        cols = [[0] * 9 for _ in range(9)]
        subs = [[[0] * 9 for _ in range(3)] for _ in range(3)]

        for i in range(9):
            for j in range(9):
                c = board[i][j]
                if c != '.':
                    c = int(c) - 1
                    rows[i][c] += 1
                    cols[c][j] += 1
                    subs[int(i/3)][int(j/3)][c] += 1
                    if rows[i][c] > 1 or cols[c][j] > 1 or subs[int(i/3)][int(j/3)][c] > 1:
                        return False
        
        return True
复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)。数独共有 81 81 81 个单元格,只需要对每个单元格遍历一次即可。
空间复杂度: O ( 1 ) O(1) O(1)。由于数独的大小固定,因此哈希表的空间也是固定的。

思路二:状态压缩 + 位运算:

    用数组来保存每个值出现的位置,需要创建三个数组,分别保存 行、列 和 3 ∗ 3 3*3 3∗3 的小矩阵,需要一定的空间开销。
    其实,可以进一步优化,通过位运算,用每一位来记录对应位置值,如果是1说明访问过,如果是0说明没访问过
java实现

class Solution {
    public boolean isValidSudoku(char[][] board) {
        int row = board.length;
        int col = board[0].length;

        int[] rows = new int[row];
        int[] cols = new int[col];
        int[][] subs = new int[3][3];

        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                char c = board[i][j];
                if (c != '.') {
                    int mask = 1 << (int)(c - '0');
                    if((rows[i] & mask) == 0 && (cols[j] & mask) == 0 && (subs[i/3][j/3] & mask) == 0) {
                        rows[i] += mask;
                        cols[j] += mask;
                        subs[i/3][j/3] += mask;
                    } else {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}
复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)。数独共有 81 81 81 个单元格,只需要对每个单元格遍历一次即可。
空间复杂度: O ( 1 ) O(1) O(1)。由于数独的大小固定,因此哈希表的空间也是固定的。

海康视觉平台VisionMaster通讯实战:三种触发方式深度解析 本文深度解析海康视觉平台VisionMaster的三种通讯触发方式:字符串触发、接收字符串事件触发和轮询D地址触发。通过实际案例和配置技巧,帮助工程师在工业场景中实现高效、稳定的设备通讯,提升视觉系统的集成效率和可靠性。 阅读详情

相关推荐

实战指南:在摩尔线程GPU上部署AI模型的完整流程

本文提供了一份详尽的实战指南,手把手教你如何在摩尔线程GPU上成功部署AI模型。内容涵盖从驱动安装、Docker环境配置,到核心的代码适配与模型运行全流程,并分享了性能调优技巧与常见避坑方法,旨在帮助开发者高效利用国产硬件进行AI应用开发。

weixin_29271263的博客 535

leetcode:36. 有效的数独

直观上,我们很容易想到使用哈希表来记录某行/某列/某个小方块出现过哪些数字,来帮助我们判断是否符合「有效数独」的定义。其实,另外,我们可以将box定义成三维数组,更好理解。

OceanStar的博客 1073

GCC调试黑科技:-fomit-frame-pointer优化下如何保证栈回溯能力

本文深入探讨了GCC编译器在启用`-fomit-frame-pointer`优化选项时如何保证栈回溯能力。通过分析`.eh_frame`段的结构与DWARF调试信息,提供了从编译选项配置到实战调试的完整解决方案,帮助开发者在性能优化与调试能力之间找到最佳平衡点。

u6v7w8x的博客 904

36. 有效的数独(超级详细)(判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可) (特别详解)

题目描述: 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字 是否有效即可。 1.数字 1-9 在每一行只能出现一次。 2.数字 1-9 在每一列只能出现一次。 3.数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 要弄清楚这个问题,就是要知道验证的算法是什么. 1.验证每一行上面是否出现了重复的数字...

汤小萌的博客 2万+

RJ45以太网接口EMC设计方案

RJ45以太网接口EMC设计方案 一、 接口概述 RJ45以太网接口是目前应用最广泛的通讯设备接口,以太网口的电磁兼容性能关系到通讯设备的稳定运行。赛盛技术应用电磁兼容设计平台(EDP)软件从接口原理图、结构设计,线缆设计三个方面来设计以太网口的EMC设计方案。 二、 接口电路 原理图的EMC设计 百兆以太网接口2KV防雷滤波设计 图1 百兆以太网接口2KV防雷滤波设计 接口电路设计概述: 本方案从EMC原理上,进行了相关的抑制干扰和抗敏感度的设计;从设计层次解决EMC问题;同时此电路兼容了百兆以太网接

兰陵笑笑生SD的博客 1万+

使用PackStack工具自动化部署OpenStack

搭建 OpenStack 环境,每个组件的安装和配置都需要熟悉其特定的依赖关系、参数设置等,对于初学者来说容易出错。PackStack 工具通过集成一系列脚本和配置文件,便于快速搭建OpenStack练习环境。CPU:支持 Intel VT - x 或 AMD - V 硬件虚拟化技术,并且要在 BIOS 里开启此功能。内存:16GB以上存储:200GB以上可用空间(2)VMware WorkStation16.0以上版本(3)远程连接工具(如Xshell、MobaXterm)

2301_80440447的博客 4094

LeetCode-36. 有效的数独

LeetCode-36. 有效的数独

Knight 698

uni-app - 解决 H5 微信公众号授权登录后,无法回退到 “上一页“ 的问题(微信登录后如何返回到触发它的那一页?无法通过 uni.navigateBack() 返回到前一页的问题?)详细教程

uniappH5微信登录重定向后无法返回到原来进入前的页面了,uni-appH5微信浏览器中授权微信登录后,无法正常回退问题,uniappH5微信登录后怎么返回上一页,uniapp公众号登陆后使用uni.navigateBack()回不去上一页,uniapp微信登录成功后返回页面后一直自动刷新页面,uniapph5授权成功后如何返回上一页,uniappH5微信登录后怎么返回到触发它的那一页去,公众号h5在授权后如何跳转回到刚进入时的页面,微信公众号H5网页返回上一页疑问,解决微信H5静默授

🏆 前端领域优质创作者 7714

【LeetCode 题解】算法:36.有效的数独

在算法领域中,数独问题是一个经典且有趣的逻辑验证题目。本题的核心任务是判断一个给定的 9x9 数独是否有效。

小高的博客 996

一文搞懂电流、电压的有效值 RMS

交流电有正半周、负半周,直接平均可能抵消成 0,但负半周一样会发热。这个交流电如果换成直流电,能产生同样发热功率时,对应的直流电压或电流”,电容耐压通常不能按 220V 选,常见会选 400V 或更高余量。所以做硬件时,220VAC 整流滤波后电容上会接近。电压/电流的有效值,也叫。如果它加在电阻上,发热按。

qq_52293640的博客 447

AgentScope 2.0 扩展开发完全指南:从中间件到模型适配器的深度实践

本文系统讲解 AgentScope 2.0 框架的五大扩展机制,涵盖中间件系统的洋葱模型与钩子设计、ChatModelBase 基类与多供应商适配器开发、工作空间(本地/Docker/E2B)的抽象接口与生命周期管理、凭据工厂与 MCP 协议集成、以及工具协议与存储后端扩展。文中提供完整的架构图、代码示例与故障排查指南,帮助开发者快速掌握 AgentScope 的插件化扩展体系。

program哲学 294

36. 有效的数独 - 力扣(LeetCode)

这个思路的关键在于通过三个检查器(行、列、宫)来跟踪每个数字是否已经出现过,并在遍历过程中不断更新这些检查器。如果在任何时刻发现重复的数字,就立即返回。以外,空格内其他数字均与 示例1 相同。但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。Python: 方法、for循环、if判断、列表、集合。Java:方法、for循环、if判断、数组。,验证已经填入的数字是否有效即可。除了第一行的第一个数字从。,否则在遍历结束后返回。

it爱好者的学习之路 2172

时间序列预测 | Python实现LSTM时间序列数据预测

目录LSTM神经网络LSTM原理LSTM数据下载LSTM程序设计导入Python包时序数据处理LSTM模块定义模型训练模型评估参数设定运行结果参考资料致谢 LSTM神经网络 长短期记忆网络——通常简称为“LSTM”——是一种特殊的 RNN,能够学习长期依赖关系。它们由Hochreiter & Schmidhuber (1997)引入,并在后续工作中被许多人提炼和推广。1它们在处理各种各样的问题时效果非常好,现在被广泛使用。LSTM 被明确设计为避免长期依赖问题。长时间记住信息实际上是他们的默认行为

前程算法屋的博客 3911

leetcode力扣36.有效的数独

判断一个9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 数字1-9在每一行只能出现一次。 数字1-9在每一列只能出现一次。 数字1-9在每一个以粗实线分隔的3x3宫内只能出现一次。 上图是一个部分填充的有效的数独。 数独部分空格内已填入了数字,空白格用'.'表示。 示例1: 输入: [ ["5","3",".",".","7",...

kaggle expert,全球排名前1000,清华计算机研究生,兴趣算法工程 705

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

LeetCode 力扣 36. 有效的数独

题目描述(中等难度) 一个 9 * 9 的数独的棋盘。判断已经写入数字的棋盘是不是合法。需要满足下边三点, 每一行的数字不能重复 每一列的数字不能重复 9 个 3 * 3 的小棋盘中的数字也不能重复。 只能是 1 - 9 中的数字,不需要考虑数独最后能不能填满。 解法一 暴力解法 需要满足三条,那就一条一条判断。 public boolean isValidSudoku(char[][]...

wind_liang的博客 1127

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

LeetCode 36 有效的数独

// 将三种情况都考虑就好了,这里用flag数组进行判重 class Solution { public boolean isValidSudoku(char[][] board){ boolean[] flag = new boolean[10]; int n = board.length; int m = board[0].len...

TIMELIMITE的专栏 337

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

LeetCode第36题_有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要,验证已经填入的数字是否有效即可。

qq_40263592的博客 1261

LeetCode 36. 有效的数独 java

LeetCode 36. 有效的数独 java 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 上图是一个部分填充的有效的数独。 数独部分空格内已填入了数字,空白格用 ‘.’ 表示。 示例 1: 输入: [ ...

lele的专栏 341

LeetCode36:有效的数独

LeetCode36:有效的数独题目说明分析C++代码 题目说明 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character ‘...

坚果 211

LeetCode 36. 有效的数独

LeetCode 36. 有效的数独 题目 36. 有效的数独 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 上图是一个部分填充的有效的数独。 数独部分空格内已填入了数字,空白格用 '.' 表示。 示例 1: 输入: [ ["5","3",".",".","7",".",".",".","."], ["6

qq_42499133的博客 390

36. 有效的数独【 力扣(LeetCode) 】

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

yyh520025的博客 880

【LeetCode】36. 有效的数独

本文介绍了如何验证9×9数独的有效性。解题关键在于检查行、列和3×3宫格中数字的唯一性。提供了三种优化方案:三次遍历(分别验证行、列、宫格)、一次遍历(同时验证三种条件)和位运算优化(使用位掩码压缩空间)。所有算法的时间复杂度均为O(1),因为数独大小固定。重点在于高效计算宫格索引和冲突检测,其中位运算版本通过掩码操作实现最优空间利用。示例显示当左上角宫格出现重复数字"8"时数独无效。

qq_32019341的博客 1122

Leetcode 36:有效的数独

Leetcode 36:有效的数独题目描述我的解法:利用set特性,将判断分为三个步骤别人家的解法 题目描述 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 上图是一个部分填充的有效的数独。 数独部分空格内已填入了数...

IcdKnight的博客 268

【LeetCode 每日一题】36. 有效的数独

这段代码的目的是验证一个 9x9 的数独棋盘是否有效。根据数独的规则,一个有效的棋盘(不一定是可解的)必须满足以下三个条件:该算法采用了一种非常高效的 “一次遍历,同步检查” 的策略。它通过一次遍历整个棋盘,同时利用三个辅助的二维数组来记录每个数字在行、列和子区域中的出现情况,从而高效地检测重复。其核心逻辑步骤如下:数据结构选择(状态记录):单次遍历:单元格处理与检查:最终结果:

最短的捷径就是绕远路,绕远路才是我的最短捷径。 1774

leetcode力扣:36. 有效的数独

基本思路: 判断数独有效要满足三个条件: 1.每行数字1-9没有重复的 2.每列数字1-9没有重复的 3.每个九宫格数字1-9没有重复的 我的思路就是,用ascall码自建哈希表,记录出现的次数,如果每行,每列或者每个九宫格同一个数字出现的次数大于一次就输出false 代码实现: class Solution { public boolean isValidSudoku(char[][] board) { //记录每行1到9每个数字出现的个数 int ...

IAMZTDSF的博客 622

LeetCode36-有效的数独

LeetCode36-有效的数独 Leetcode / 力扣 36. 有效的数独: 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 注意: 一个有效的数独(部分已被填充)不一定是可解的。 只需要根据以上规

baodream的博客 420
上一篇: LeetCode-35 - 搜索插入位置
下一篇: LeetCode-37 - 解数独
CodAlun
博客等级 码龄8年 46粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值