LeetCode:36. Valid Sudoku(Medium)

1. 原题链接

https://leetcode.com/problems/valid-sudoku/description/

 

2. 题目要求

给定一个 9✖️9 的数独,判断该数独是否合法

数独用字符类型的二维数组表示,为空的地方用 '.' 代替 

合法应满足以下要求:(1)每一列的数字不重复;(2)每一行的数字不重复;(3)3✖️3区域内不存在重复值;下图是一个合法的数独:

 

3. 解题思路

根据合法应满足的三个要求依此来进行判断:

(1)行和列是否存在重复值:可以通过两层for循环遍历二维数组,然后使用HashSet,因为HashSet不允许存在重复值。依此将遍历到的数字加入HashSet,无法加入时则证明存在重复,返回false;

(2)3✖️3区域内是否存在重复值:

 难点:如何经过一次内部for循环就能遍历到一个 3✖️3 区域

假设我们现在要得到红框圈住的3✖️3区域,第一层for循环 i 此时为“1”,第二层for循环 j 从“0”遍历到“8”。如何确保rowIndex和columnIndex的取值范围都是 1~3?

可以发现 “j/3” 和 “j%3”的范围是 0~2,此时的 i =1,因此我们要对这三者进行利用,就能保证rowIndex和columnIndex的取值范围都是 1~3。

 

4. 代码实现

 1 import java.util.HashSet;
 2 
 3 public class ValidSudoku36 {
 4     public static void main(String[] args) {
 5         char[][] board = {{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
 6                 {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
 7                 {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
 8                 {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
 9                 {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
10                 {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
11                 {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
12                 {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
13                 {'.', '.', '.', '.', '8', '.', '.', '7', '9'}};
14         System.out.println(isValidSudoku(board));
15     }
16 
17     public static boolean isValidSudoku(char[][] board) {
18         for (int i = 0; i < board.length; i++) {
19             HashSet<Character> row = new HashSet<Character>();
20             HashSet<Character> column = new HashSet<Character>();
21             HashSet<Character> cube = new HashSet<Character>();
22             for (int j = 0; j < board.length; j++) {
23                 if (board[i][j] != '.' && !row.add(board[i][j]))
24                     return false;
25 
26                 if (board[j][i] != '.' && !column.add(board[j][i]))
27                     return false;
28 
29                 int rowIndex = 3 * (i / 3);
30 
31                 int columnIndex = 3 * (i % 3);
32                 System.out.print(rowIndex + j / 3+",");
33                 System.out.print(columnIndex + j % 3+"  ");
34                 if (board[rowIndex + j / 3][columnIndex + j % 3] != '.' && !cube.add(board[rowIndex + j / 3][columnIndex + j % 3]))
35                     return false;
36             }
37             System.out.println("");
38             System.out.println("");
39         }
40         return true;
41     }
42 }

 

posted @ 2018-01-06 10:35  一只敲码的猫  阅读(370)  评论(0编辑  收藏  举报