题目描述:
leetcode 36.有效的数独
* 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
上图是一个部分填充的有效的数独。
数独部分空格内已填入了数字,空白格用 '.' 表示。
示例 1:
输入:
[
["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:
输入:
[
["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 存在, 因此这个数独是无效的。
说明:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
给定数独序列只包含数字 1-9 和字符 '.' 。
给定数独永远是 9x9 形式的。
数字0-9 的ASCII 码值48-57
. 的ASCII 46
问题分析:
第一种方法:从3*3九宫格开始,然后走每一行,每一列,查找相同,但是报的错误还没有解决,所以先提供一个思路
第二种方法:有点类似,设置成三个数组进行查重,对数组的数据进行true的验证
代码展示(已验证):
import java.util.Arrays;
public class isValidSudoku {
public static void main(String[] args) {
char[][] 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'},
};
if(isvalidsudoku2(board)) {
System.out.println("true");
}
// System.out.println("\n数独的值:"+);
}
第一种方法
static boolean isvalidsudoku(char[][] board) {
char[] tmp = new char[9];
int num1=0,num2=3,m=0;
String tmp1;
char[] tmp2;
//九宫格部分
while(num2<12) {
for(int i=num1;i<num2;i++)
{
for(int j=num1;j<num2;j++) {
// System.out.print(board[i][j]+" ");
if(board[i][j] != '.') {
tmp[m++] = board[i][j];
}
}
}
num1 +=3;
num2 +=3;
Arrays.sort(tmp);
for(int i=0;i<tmp.length;i++)
{
if(tmp[i] == ' ')
System.out.print("有空格");
}
tmp1 = tmp.toString().trim();
System.out.print("\n"+tmp1);
tmp2 = tmp1.toCharArray();
for(int i=0;i<tmp2.length;i++)
System.out.print(tmp2[i]+" ");
System.out.print("\n");
for(int i=0;i<tmp.length;i++) {
System.out.print(tmp[i]+" ");
}
for(int i=0; i<tmp.length-1 ;i++) {
if(tmp[i] == tmp[i+1])
{
System.out.print("\n九宫格循环数组值有相同的");
System.out.print("\n相同的两个值为:"+tmp[i]+"第二个值为:"+tmp[i+1]);
return false;
}
}
tmp = null;
m=0;
}
// 9行9列 部分
for(int i=0;i<9;i++) {
for(int j=0;j<9;j++) {
if(board[i][j] != '.') {
tmp[m++] = board[i][j];
}
}
Arrays.sort(tmp);
for(int k=0; k<tmp.length-1 ;k++) {
if(tmp[i] == tmp[i+1])
{
System.out.print("九行九列循环数组值有相同的");
return false;
}
}
tmp = null;
m=0;
}
return true;
}
第二种方法
//row数组:存储原数组borad的每一行数字到row数组的每一行上进行检测,
//col数组:存储board数组的每一列数字到col数组的每一行进行检测,
//block数组:存储原数组borad的每一个九宫格到block数组的每一行上进行检测;
static boolean isvalidsudoku2(char[][] board) {
// 记录某行,某位数字是否已经被摆放
boolean[][] row = new boolean[9][9];
// 记录某列,某位数字是否已经被摆放
boolean[][] col = new boolean[9][9];
// 记录某 3x3 宫格内,某位数字是否已经被摆放
boolean[][] block = new boolean[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '1';
int blockIndex = i / 3 * 3 + j / 3;
if (row[i][num] || col[j][num] || block[blockIndex][num]) {
return false;
} else {
row[i][num] = true;
col[j][num] = true;
block[blockIndex][num] = true;
}
}
}
}
return true;
}
}
泡泡:
数独这个问题关键还是在于 怎么查重,查重的分组要怎么分,有没有更快更好的分组方法
第二个方法的关于数字大小的利用还是很巧妙的