我是靠谱客的博主 迷人糖豆,最近开发中收集的这篇文章主要介绍力扣初级算法-06-数组-有效的数独学习目标:学习内容:学习笔记:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

学习目标:

本次学习目标为 力扣初级算法-数组,其中主要的LC如下:

  • 有效的数独

学习内容:

  1. 有效的数独 -----(链接)
    请你判断一个 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
    • 当所有元素都循环完,即可直接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-数组-有效的数独学习目标:学习内容:学习笔记:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部