1 Star 0 Fork 0

临窗旋墨 / basics

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
J0037_H_SolveSudoku.java 5.87 KB
一键复制 编辑 原始数据 按行查看 历史
package pers.vic.basics.leetcode;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* @author Vic.xu
* @description: 37. 解数独{@literal https://leetcode-cn.com/problems/sudoku-solver/}
* @date: 2020/12/1 0001 11:13
*/
public class J0037_H_SolveSudoku {
/*
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
提示:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
*/
/**
* 借鉴36题的 校验数独是否合法的方法
*
* @param board
*/
public static void solveSudoku(char[][] board) {
// 每个元素存储整行的数字 按位存储 如 先存元素4 --> 000000100, 再存元素1 --> 000000101
int[] rows = new int[L];
//每个元素存一整列 如,[0] 存 第一列 [1]存第二列
int[] columns = new int[L];
// 每个元素存 一个3X3的九宫格: [index] = i/3*3 + j/3
int[] boxes = new int[L];
//把数字初始化到 上述三个元素
for (int i = 0; i < L; i++) {
for (int j = 0; j < L; j++) {
char cur = board[i][j];
// 分别存入所在行、列和九宫格 是否已经包含当前元素
checkAndPut(cur, i, j, rows, columns, boxes);
}
}
dfs(board, 0, 0, rows, columns, boxes);
}
/**
* 判断当前行当前列当前九宫格是否包含 均不包含则存入相应位置
*/
public static boolean checkAndPut(char item, int row, int column, int[] rows, int[] columns, int[] boxes) {
int n = item - '0';
boolean rowContain = (rows[row] >> n & 1) == 1;
boolean columnContain = (columns[column] >> n & 1) == 1;
int boxIndex = row / 3 * 3 + column / 3;
boolean boxContain = (boxes[boxIndex] >> n & 1) == 1;
if (rowContain || columnContain || boxContain) {
return false;
}
rows[row] = rows[row] | 1 << n;
columns[column] = columns[column] | 1 << n;
boxes[boxIndex] = boxes[boxIndex] | 1 << n;
return true;
}
/**
* 把放入对应行列box的下标对应的位数重新置为0
*/
public static boolean rollbackIndex(char item, int row, int column, int[] rows, int[] columns, int[] boxes) {
int n = item - '0';
int boxIndex = row / 3 * 3 + column / 3;
remoteIndex(rows, row, n);
remoteIndex(columns, column, n);
remoteIndex(boxes, boxIndex, n);
return true;
}
// 从某一个下标中删除:即把某位置为0
private static void remoteIndex(int[] nums, int index, int n) {
int ret = nums[index] & ~(1 << n);
nums[index] = ret;
}
static int L = 9;
public static boolean dfs(char[][] board, int row, int column, int[] rows, int[] columns, int[] boxes) {
//结束条件:填写完毕
if (column == L) {
row++;
column = 0;
}
if (row == L) {
return true;
}
if ('.' == board[row][column]) {
int boxIndex = row / 3 * 3 + column / 3;
//从1 到9 开始填写到当前位置
for (int i = 1; i <= 9; i++) {
char cur = (char) (i + '0');
// 分别验证所在行、列和九宫格 是否已经包含当前元素
boolean checkAndPut = checkAndPut(cur, row, column, rows, columns, boxes);
// 如果不能放当前字符 则换其他字符尝试
if (!checkAndPut) {
continue;
}
//可以存放 则继续方下一个位置
board[row][column] = cur;
if (dfs(board, row, column + 1, rows, columns, boxes)) {
return true;
}
//撤销当前位置 ,以及撤销当前行列box中的位置
board[row][column] = '.';
rollbackIndex(cur, row, column, rows, columns, boxes);
}
} else {
return dfs(board, row, column + 1, rows, columns, boxes);
}
return false;
}
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'}};
for (int i = 0; i < board.length; i++) {
System.out.println(Arrays.toString(board[i]));
}
solveSudoku(board);
System.out.println("");
for (int i = 0; i < board.length; i++) {
System.out.println((i+1) +"->" + Arrays.toString(board[i]));
}
}
}
Java
1
https://gitee.com/xuqiudong/basics.git
git@gitee.com:xuqiudong/basics.git
xuqiudong
basics
basics
master

搜索帮助