36. 有效的数独
题目:
思路:
【1】由于矩阵大小固定,而且数值也是固定的范围,采用int数组,以下标来替代值,以值来表示个数,就可以清晰的知道该行,该列,或者该小矩阵是否出现过重复的数值,如 rows[2][3] = 2 , 则表示第二列中数值3出现了两次,基于每一列或者每一行中1-9都只会出现一次的条件就可以判断出该矩阵不符合条件。
代码展示:
//时间1 ms 击败 99.98% //内存42 MB 击败 37.84% class Solution { public boolean isValidSudoku(char[][] board) { // 因为题目已经固定了是9*9的矩阵,而且出现的数字是1-9, // 故可以用下标代表值,用值来表示个数,如果个数大于1则代表重复出现的问题 // 标记列的数据, int[][] rows = new int[9][9]; // 标记行的数据, int[][] columns = new int[9][9]; // 标记矩形的数据, int[][][] subboxes = new int[3][3][9]; // 故这里其实是只需要遍历一遍 // 遍历列 for (int i = 0; i < 9; i++) { // 遍历行 for (int j = 0; j < 9; j++) { char c = board[i][j]; // 不为空格的情况下 if (c != '.') { int index = c - '0' - 1; rows[i][index]++; columns[j][index]++; subboxes[i / 3][j / 3][index]++; // 每次填充完都要判断是否出现重复值了,如果出现则返回不满足 if (rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i / 3][j / 3][index] > 1) { return false; } } } } return true; } } //时间1 ms 击败 99.98% //内存41.7 MB 击败 48.6% class Solution { public boolean isValidSudoku(char[][] board) { int[][] rows = new int[9][9]; int[][] columns = new int[9][9]; int[][][] subboxes = new int[3][3][9]; for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if (board[i][j] == '.') { continue; } int index = board[i][j] - '0' - 1; if (rows[i][index] >= 1) { return false; } if (columns[j][index] >= 1) { return false; } if (subboxes[i / 3][j / 3][index] >= 1) { return false; } rows[i][index]++; columns[j][index]++; subboxes[i / 3][j / 3][index]++; } } return true; } }