问题描述:
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 '.'
.
A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
原问题链接:https://leetcode.com/problems/valid-sudoku/
问题分析
对于数独问题来说,我们首先要熟悉它本身的规则。它是一个9 x 9的矩阵。作为一个合法的数独表示,它要求里面每一行,每一列都取值自1到9,但是这些数字只能出现1次,而且不能有重复。同时,如果将这个矩阵9等分的话,则有9个3 x 3的小矩阵。对于这些小的矩阵来说,它们里面的每个数字也只能出现一次不能重复。
所以要解决这个问题一个最直观的办法就是判断它的每一行,每一列以及每个小矩阵是否都符合要求。按照这个思路,我们每次判断每一行是否合法的时候,只需要用一个set,将碰到的元素和set进行对比。如果该元素非法,则返回false。如果该元素是'.',不用继续比较,继续下一步,如果集合里有这个元素,那么说明该矩阵非法,返回false。
这里稍微困难一点的地方就是怎么来判断里面的9个小矩阵呢?假设从最左上角的那个矩阵开始,也就是这个时候最起始点的索引位置是i = 0, j = 0。按照我们每一行一行从上到下遍历的顺序,它的访问方式如下图:
这里每一条横线可以表示i的值。按照这个顺序,它们的索引位置变化按照如下的顺序(0, 0) -> (0, 1) -> (0, 2) -> (1, 0) -> (1, 1) -> (1, 2)。对于这个矩阵来说,它总共有9个元素。如果我们换一种方式来考虑。假设给定了初始的点i, j,不用i, j构成的双重循环,有没有别的办法来遍历整个矩阵呢?针对这种情况,我们可以用一个变量k来循环。从0到9。对于里面对应的每个位置的关系可以定义如下: i = i + k / 3; j = j + k % 3;
所以在给定初始i, j的情况下会有这么一个表达方式:
for(int k = 0; k < 9; k++) board[i + k / 3][j + k % 3] = xxx;
它和我们使用如下的方式来遍历是等价的:
for(int l = i; l < i + 3; l++) { for(int r = j; r < j + 3; r++) board[l][r] = xxx; }
上述的表达式能够简化部分代码。剩下的部分就是该怎么把这个部分和所有i, j的位置给串起来。对于里面的9个小矩阵,我们现在只需要找到它们每个矩阵最开始的位置。很直观,它们的位置如下:(0, 0) (0, 3), (0, 6) (3, 0), (3, 3) (3, 6) (6, 0), (6, 3) (6, 6)。我们可以很直接的用两个循环就解决了:
for(int i = 0; i < 9; i += 3) { for(int j = 0; j < 9; j += 3) { // xxxx } }
最终可以得到如下的代码:
public class Solution { public boolean isValidSudoku(char[][] board) { if(board == null || board.length != 9 || board[0].length != 9) return false; int n = board.length; for(int i = 0; i < n; i++) { Set<Character> set = new HashSet<>(); for(int j = 0; j < n; j++) { if(!isValid(set, board, i, j)) return false; } } for(int j = 0; j < n; j++) { Set<Character> set = new HashSet<>(); for(int i = 0; i < n; i++) { if(!isValid(set, board, i, j)) return false; } } for(int i = 0; i < n; i += 3) { for(int j = 0; j < n; j += 3) { Set<Character> set = new HashSet<>(); for(int k = 0; k < n; k++) if(!isValid(set, board, i + k / 3, j + k % 3)) return false; } } return true; } private boolean isValid(Set<Character> set, char[][] board, int i, int j) { if(board[i][j] == '.') return true; if(board[i][j] < '1' || board[i][j] > '9') return false; if(set.contains(board[i][j])) return false; set.add(board[i][j]); return true; } }
上述代码的时间复杂度为O(N ^ 2)。
总结
这个问题的思路并不复杂,重要的是要能找到一个对问题解决方法的一个简洁的表达方式。
相关推荐
Valid Sudoku 数组 遍历 Sudoku Solver 深度优先遍历 回溯 先检查后修改 Group Anagrams 排序 unordered_map Minimum Window Substring 两个指针遍历 map Maximal Rectangle 栈 局部递增 或者 动态规划 Binary Tree ...
Valid Sudoku linked list Palindrome linked list Linked List Cycle trees Convert Sorted Array to Binary Search Tree string and search First Bad Version Dynamic Programing *** Climbing Stairs Set Matrix...
lru cache leetcode LeetCode 这个库用于总结leetcode中遇到的习题 常用数据结构习题总结 1.线性表 解决进度 No. Describition mark 1 Remove Duplicates from ...Valid Sudoku 15 Trapping Rain W
c语言入门 C语言_leetcode题解之36-valid-sudoku.c
js js_leetcode题解之第36-valid-sudoku.js
# [LeetCode](https://leetcode.com/problemset/algorithms/) ![Language](https://img.shields.io/badge/language-Python%20%2F%20C++%2011-orange.svg) [![License]...
leetcode添加元素使和等于 leetcode_py Python version of leetcode problems 33 Search in Rotated Sorted Array 问题:找到经过旋转的有序数组中是否有目标的数。 解法:基于二分的方法,根据 ...Valid Sudoku 问题
- Valid Sudoku: 验证一个9x9的数独是否有效。 - Sudoku Solver: 解数独问题,即给出一个部分填充的数独,要求填充剩余空格。 - Count and Say: 第n个数是“1”,“21”,“1211”,“111221”等描述的下一个数。 - ...
leetcode 2 密码节 以及在竞争性编程中组织了第一个 1.5 个月的指导计划。 该计划将包括 2 个阶段。 学习阶段: 学员将与导师配对,在为期 1 个月的时间里,学员将获得学员每天需要尝试的不同难度级别的学习材料和...
- **2.1.14 Valid Sudoku** - 判断给定的数独是否有效。 - 实现思路:分别检查行、列和小九宫格是否包含重复数字。 - **2.1.15 Trapping Rain Water** - 计算雨水能够困住的水量。 - 实现思路:使用动态规划...
#### 二、Valid Sudoku - **知识点:**数组、哈希表。 - **题目描述:**判断一个9x9的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可: - 每行中的数字必须是1-9,并且不能重复。 - 每列中的...
2. 题目36:有效的数独 (Valid Sudoku) 验证一个9x9的数独是否有效,需要检查每一行、每一列以及每个小九宫格内的数字是否唯一。可以使用哈希表来快速检查数字是否存在。 3. 题目87:扫描线排序 (Scramble String)...
#LintCode题解##PDF下载本书即将由电子工业出版社出版,因此这个Repo更新会略落后于纸质版。欢迎大家购买纸质版,支持我持续更新本书。C++ 文件夹下是C++版,内容一摸一样,代码是用C++写的,Java 文件夹下是Java版...
在本压缩包中,我们关注的是一个Python编程相关的学习资源,特别针对LeetCode平台上的第36题——“有效的数独”(Valid Sudoku)。这是一道典型的算法问题,经常出现在IT求职面试中,尤其是对Python程序员来说。让...
4. "Valid Sudoku":使用二维HashSet检查9x9的数独是否合法。 通过不断练习LeetCode中的Java解决方案,不仅可以巩固和深化对Java语言的理解,还能提升算法思维和问题解决能力,对于程序员的职业发展大有裨益。在...
除了基本算法,LeetCode还包含一些涉及复杂数据结构和算法的问题,如"Longest Increasing Subsequence.py"(最长递增子序列)、"Valid Sudoku.py"(验证数独)以及"Minimum Spanning Tree.py"(最小生成树)。...
- **Valid Sudoku**:检查一个数独是否有效,即每一行、每一列以及每一个宫格内的数字是否都在1到9之间且不重复。 这些知识点在编程竞赛、算法设计、网络分析、图形理论等领域都有广泛应用。通过LeetCode等在线...
Practice-Leetcode 这是一个Chinese School Girl:China:用来练习leetcode的文档.每道下面的题都有详细的解题思路,和知识点分析,尽请参考。...36.Valid Sudoku set去重复 2018/04/19: 038.Count and Say 递归 040.C