- 问题描述
- 判断一个 9x9 的数独是否有效。需要满足三个条件:
1. 数字 1-9
在每一行只能出现一次
2. 数字 1-9
在每一列只能出现一次
3. 数字 1-9
在每一个以粗实线分隔的 3x3
宫内只能出现一次。
- 解决思路
- 前两个要求比较容易好解决,对每行、列的数字都用一个映射来计数,key 为 1-9 的数字,value 为该数字出现的次数。
- 关键是第二个要求,在 9X9 的 方格里总共有 9 个 3X3 的小方格。可以根据 i, j 坐标计算出是第几个方格,用9个映射来存储数字及其出现的次数。或者用二维信息(i,j)来代表当前元素是在哪个小方格。
- Java 代码如下:
1 public boolean isValidSudoku(char[][] board) { 2 HashMap<Integer, Integer> [] rows = new HashMap[9]; 3 HashMap<Integer, Integer> [] columns = new HashMap[9]; 4 HashMap<Integer, Integer> [] boxes = new HashMap[9]; 5 for (int i = 0; i < 9; i++) { 6 rows[i] = new HashMap<Integer, Integer>(); 7 columns[i] = new HashMap<Integer, Integer>(); 8 boxes[i] = new HashMap<Integer, Integer>(); 9 } 10 // validate a board 11 for (int i = 0; i < 9; i++) { 12 for (int j = 0; j < 9; j++) { 13 char num = board[i][j]; 14 if (num != '.') { 15 int n = (int)num; 16 // 区分当前是第几个小格子,9X9的格子阵里面有 9 个3X3的小格子。 17 int box_index = (i / 3 ) * 3 + j / 3; 18 // 对该行,该列,该小方格进行健值对的添加。 19 rows[i].put(n, rows[i].getOrDefault(n, 0) + 1); 20 columns[j].put(n, columns[j].getOrDefault(n, 0) + 1); 21 boxes[box_index].put(n, boxes[box_index].getOrDefault(n, 0) + 1); 22 // 判重 23 if (rows[i].get(n) > 1 || columns[j].get(n) > 1 || boxes[box_index].get(n) > 1) 24 return false; 25 } 26 } 27 } 28 return true; 29 }
2. Python 代码如下:
1 class Solution: 2 def isValidSudoku(self, board): 3 """ 4 :type board: List[List[str]] 5 :rtype: bool 6 """ 7 // 可以直接用一个集合,就可以存储所有的需要判重的健值对 8 count = set() 9 for i in range(9): 10 for j in range(9): 11 if board[i][j] != '.': 12 cur = board[i][j] 13 if ((i,cur) in count) or ((cur,j) in count) or ((i//3, j//3, cur) in count): 14 print("(i,j)=(%s,%s)"%(i, j)) 15 return False 16 # row 17 count.add((i, cur)) 18 # column 19 count.add((cur, j)) 20 # square 21 count.add((i//3,j//3,cur)) 22 return True
- Java 代码如下: