LeetCode初级算法10:有效的数独

该博客主要讨论如何实现一个有效的9x9数独验证算法。通过遍历数独矩阵的每一行、每一列以及每个3x3宫格,检查数字1-9是否出现且仅出现一次,从而判断数独是否符合规则。文中提供了两种暴力破解的Java实现方式,一种是检查过程中额外记录数量,另一种是在添加到集合时直接判断是否存在,优化了空间使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🐕请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。

数字 1-9 在每一列只能出现一次。

数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

🐱注意:

一个有效的数独(部分已被填充)不一定是可解的。

只需要根据以上规则,验证已经填入的数字是否有效即可。

在这里插入图片描述

输入:board =
[[“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”]]
输出:true

示例 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
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

🐖提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 ‘.’

🐒思路:

1、暴力破解

遍历每一行 存入set 判断最后的结果和存入set的数量是否一直 如果不一致证明有重复
遍历每一列 存入set 判断最后的结果和存入set的数量是否一直 如果不一致证明有重复
遍历每个 9*9的格子 存入set 判断最后的结果和存入set的数量是否一直 如果不一致证明有重复

上代码
		//每行是否违规
		 for(int row = 0; row < 9 ; row++) {
			 Set<Character> set = new HashSet<>();
			 int count = 0;
			 for(int col = 0; col < 9 ; col++) {
				 if(board[row][col] == '.') {
					 continue;
				 }else {
					 count++;
					 set.add(board[row][col]);
				 }
			 }
			 if(count != set.size()) {
				 return false;
			 }
		 }
		 //每列是否违规
		 for(int col = 0; col < 9 ; col++) {
			 Set<Character> set = new HashSet<>();
			 int count = 0;
			 
			for(int row = 0; row < 9 ; row++) {
				if(board[row][col] == '.') {
					continue;
				}else {
					count ++;
					set.add(board[row][col]);
				}
			}
			 if(count != set.size()) {
				 return false;
			 }
		 }
		 // 3 * 3 是否违规
		 // cur 当前二维数组的行
		 for(int cur = 0; cur < 9 ; cur+=3) {
			 for(int i = 0; i < 9; i+=3) {
				 Set<Character> set = new HashSet<>();
				 int count = 0;
				 for(int index = cur; index < cur+3; index ++) {
					for(int col = i; col < i + 3; col ++) {
						if(board[index][col] == '.') {
							continue;
						}else {
							count++;
							set.add(board[index][col]);
						}
					}
				 }
				 if(count != set.size()) {
					 return false;
				 }
			 }
		 }
		 return true;
	 }

在这里插入图片描述

2、暴力破解 优化一定空间版本

🦆存入set之前 判断是否存在即可 无需再多一个变量记住数量
上代码
public static boolean isValidSudoku_V2(char[][] board) {
		 //每行是否违规
		 for(int row = 0; row < 9 ; row++) {
			 Set<Character> set = new HashSet<>();
			 for(int col = 0; col < 9 ; col++) {
				 if(board[row][col] == '.') {
					 continue;
				 }else {
					 if(!set.contains(board[row][col])) {
						 set.add(board[row][col]);
					 }else {
						 return false;
					 }
				 }
			 }
		 }
		 //每列是否违规
		 for(int col = 0; col < 9 ; col++) {
			 Set<Character> set = new HashSet<>();
			for(int row = 0; row < 9 ; row++) {
				if(board[row][col] == '.') {
					continue;
				}else {
					 if(!set.contains(board[row][col])) {
						 set.add(board[row][col]);
					 }else {
						 return false;
					 }
				}
			}
		 }
		 // 3 * 3 是否违规
		 // cur 当前二维数组的行
		 for(int cur = 0; cur < 9 ; cur+=3) {
			 for(int i = 0; i < 9; i+=3) {
				 Set<Character> set = new HashSet<>();
				 for(int index = cur; index < cur+3; index ++) {
					for(int col = i; col < i + 3; col ++) {
						if(board[index][col] == '.') {
							continue;
						}else {
							 if(!set.contains(board[index][col])) {
								 set.add(board[index][col]);
							 }else {
								 return false;
							 }
						}
					}
				 }
			 }
		 }
		 return true;
	 }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值