LeetCode-37. Sudoku Solver (JAVA)(数独游戏解集)

来源:互联网 发布:java中gbk转utf8 编辑:程序博客网 时间:2024/06/09 21:04

37. Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.

LeetCode-36. Valid Sudoku (JAVA)(有效数独)

N皇后问题。就是一点点尝试着填数,不行的话就回溯,直到都填满就返回。

如果对一个格子尝试从0~9都不行,那么说明整个sudoku无解,返回false就好。

对整个棋盘所有'.'都填完了,那么就可以返回true了。

 LeetCode-51. N-Queens (JAVA)(打印N皇后解集)

LeetCode-52. N-Queens II (JAVA)(N皇后解集个数)

public void solveSudoku(char[][] board) {if (board == null || board.length == 0)return;dfs(board);}// 也是按照行进行放置,只不过n后问题每行只放一个Q,不重复放置,是一层循环// 而此题需要放置多个数字,还不能重复,所以是一个三层循环private boolean dfs(char[][] board) {for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == '.') {for (char num = '1'; num <= '9'; num++) {// 尝试if (validate(board, i, j, num)) {board[i][j] = num;if (dfs(board))return true;else// 回溯board[i][j] = '.';}}// 如果对一个格子尝试从0~9都不行,// 那么说明整个sudoku无解,返回falsereturn false;}}}// 对整个棋盘所有'.'都填完了,那么就可以返回true了。return true;}// 通常验证函数需要单独解耦合private boolean validate(char[][] board, int i, int j, char c) {// check column(列)for (int row = 0; row < 9; row++)if (board[row][j] == c)return false;// check row(行)for (int col = 0; col < 9; col++)if (board[i][col] == c)return false;// check cube(小九宫格)int rIdx = i / 3 * 3;int cIdx = j / 3 * 3;for (int row = rIdx; row < rIdx + 3; row++)for (int col = cIdx; col < cIdx + 3; col++)if (board[row][col] == c)return false;return true;}
discuss 解法,简介

public void solveSudoku(char[][] board) {dfs(board, 0);}// 思想是如果是数字直接进入下一层递归// 如果是.就填入并且验证合法性,验证通过进入下一层递归private boolean dfs(char[][] board, int d) {if (d == 81)return true;int i = d / 9, j = d % 9;// found solution(寻找解集)// 如果是数字,进入下一层递归if (board[i][j] != '.')// prefill number skip// 预填数字return dfs(board, d + 1);// 如果不是数字,填入数字并且验证boolean[] flag = new boolean[10];validate(board, i, j, flag);for (int k = 1; k <= 9; k++) {// flag[k]为true,说明此数字可用if (flag[k]) {// 填入board[i][j] = (char) ('0' + k);// 验证通过进入下一层递归if (dfs(board, d + 1))// 如果下一层验证通过返回truereturn true;}}// if can not solve, in the wrong path, change// back to '.' and outboard[i][j] = '.';return false;}private void validate(char[][] board, int i, int j, boolean[] flag) {Arrays.fill(flag, true);for (int k = 0; k < 9; k++) {if (board[i][k] != '.')flag[board[i][k] - '0'] = false;if (board[k][j] != '.')flag[board[k][j] - '0'] = false;int r = i / 3 * 3 + k / 3;int c = j / 3 * 3 + k % 3;if (board[r][c] != '.')flag[board[r][c] - '0'] = false;}}


Reference:http://rleetcode.blogspot.com/2014/01/sudoku-solver-java.html

0 0
原创粉丝点击