概述
学习目标:
本次学习目标为 力扣初级算法-数组,其中主要的LC如下:
- 有效的数独
学习内容:
- 有效的数独 -----(链接)
请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。示例1:
示例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
解题思路:
-
解法一:
-
边界问题:
- 未输入不分用 “.” 来代替
- 入参是字符串,故需要转换为 数字来处理
-
代码逻辑过程:
- 声明三组二维数组,分别代表 行 line 、列 column 、3*3 cell 三个部分
- 循环遍历二维数据,根据二维坐标拿到当前循环的元素对应的数值 -num
- 判断是否重复逻辑
- 拿当前元素的数值num,作为 line、column、cell 二维数组中的二维的index,在插入之前先判断,当前index 下是否已存在数值,
- 如果已存在,则表明上述循环的数组元素已出现过,此时可直接 return false
- 如果不存在,则表明上述循环的数组的元素未出现,则直接在对应的 index 下写入 元素的数值 num
- 拿当前元素的数值num,作为 line、column、cell 二维数组中的二维的index,在插入之前先判断,当前index 下是否已存在数值,
- 当所有元素都循环完,即可直接return ture
-
关键点:
- 将元素的数值转换数组的index,判断元素的index下是否有值来判断是否已写入。
- 空间换空间
-
代码实现:
public static boolean isValidSudoku(char[][] board) {
int length = board.length;
//二维数组line表示的是对应的行中是否有对应的数字,比如line[0][3]
//表示的是第0行(实际上是第1行,因为数组的下标是从0开始的)是否有数字3
int line[][] = new int[length][length];
int column[][] = new int[length][length];
int cell[][] = new int[length][length];
for (int i = 0; i < length; ++i)
for (int j = 0; j < length; ++j) {
//如果还没有填数字,直接跳过
if (board[i][j] == '.')
continue;
//num是当前格子的数字
int num = board[i][j] - '0' - 1;
//k是第几个单元格,9宫格数独横着和竖着都是3个单元格
int k = i / 3 * 3 + j / 3;
//如果当前数字对应的行和列以及单元格,只要一个由数字,说明冲突了,直接返回false。
//举个例子,如果line[i][num]不等于0,说明第i(i从0开始)行有num这个数字。
if (line[i][num] != 0 || column[j][num] != 0 || cell[k][num] != 0)
return false;
//表示第i行有num这个数字,第j列有num这个数字,对应的单元格内也有num这个数字
line[i][num] = column[j][num] = cell[k][num] = 1;
}
return true;
}
- 测试用例:
public static void main(String[] args) {
char[][] chars = {
{'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'}
};
isValidSudoku(chars);
}
-
解法二: 使用hashSet解决
-
边界问题: 无
-
代码逻辑过程:
- 分别先对 行liine 列 column 进行判空(等于 ‘.’),同时写入 Set 为 ture
- 考虑 3*3 部分
- 将行超过部分转换到列中
-
代码实现:
public static boolean isValidSudoku02(char[][] board) {
for (int i =0 ; i < 9; i++){
HashSet<Object> lineSet = new HashSet<>();
HashSet<Object> columnSet = new HashSet<>();
HashSet<Object> cellSet = new HashSet<>();
for (int j = 0; j < 9; j++){
boolean isNotEmpty = board[i][j] != '.';
if (isNotEmpty && !lineSet.add(board[i][j])){
return false;
}
if (isNotEmpty && !columnSet.add(board[i][j])){
return false;
}
int a = (i/3)*3 + j/3;
int b = (i%3)*3 + j%3;
if (board[a][b] != '.' && cellSet.add(board[a][b])){
return false;
}
}
}
return true;
}
学习笔记:
最后
以上就是迷人糖豆为你收集整理的力扣初级算法-06-数组-有效的数独学习目标:学习内容:学习笔记:的全部内容,希望文章能够帮你解决力扣初级算法-06-数组-有效的数独学习目标:学习内容:学习笔记:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复