leetcode 37. Sudoku Solver

一 题目

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

A sudoku solution must satisfy all of the following rules:

  1. Each of the digits 1-9 must occur exactly once in each row.
  2. Each of the digits 1-9 must occur exactly once in each column.
  3. Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.

leetcode 37. Sudoku Solver_第1张图片

A sudoku puzzle...

 

Note:

  • The given board contain only digits 1-9 and the character '.'.
  • You may assume that the given Sudoku puzzle will have a single unique solution.
  • The given board size is always 9x9.

二 分析

求解数独,hard级别。

数独的题目: leetcode 36. Valid Sudoku 求解是否符合规则。

 

这个题目还要复杂,在上个题目的valid基础上做了拓展。主要还是使用了回溯法:对于每个空着格子填入1到9,每填入一个数字都判定其是否合法,如果合法就继续下一次,或者失败回溯到上一个点时把数字设回 '.',。

   判断新加入的数字是否合法时,只需要判定当前数字是否合法,不需要判定这个数组是否为数独数组,因为之前加进的数字都是合法的。校验合法的方法跟上一篇类似:分别校验行、列、及小3*3区域。

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'}
		};
		solveSudoku(board);
		System.out.println(JSON.toJSON(board));
	}

	public static void solveSudoku(char[][] board) {
        
		helper(board);
	}	
	
	private static  boolean  helper(char[][] board) {
		//遍历整个数独的所有字符
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				 //非空跳过
				 if (board[i][j] != '.') {
		                continue;
		            }
				 //尝试遍历要填充的数字
				 for(char k='1';k<='9';k++){
					 if (isValid(board, i, j, k)) {
						 board[i][j]=k;
						//填充完毕之后继续调用该函数填充下一个点
						 if(helper(board)){
							 return true;
						 }
						//如果solve(board)返回false,则说明前面的数字填充有误,将其还原,尝试下一个数字
						 board[i][j]='.';
					 }
					 
				 }
				//如果1-9都无法满足则说明之前的数字填错了,回溯到原始状态
				  return false;
			}			
		}//所有的空格被填充完毕,返回true
		 return true; 
    }

	private static boolean isValid(char[][] board, int i, int j, char k) {
		
		for(int x=0;x<9;x++){
			if(board[x][j]!='.' && board[x][j]== k){
				return false;
			}	

			if(board[i][x] !='.' && board[i][x]==k){
				return false;
			}
			
			if(board[3*(i/3)+x/3 ][3*(j/3)+x%3] !='.' && board[3*(i/3)+x/3 ][3*(j/3)+x%3]==k){
				return false;
			}
		}		
		
		return true;
	}
	

 

Runtime: 6 ms, faster than 70.34% of Java online submissions for Sudoku Solver.

Memory Usage: 34.7 MB, less than 71.93% of Java online submissions forSudoku Solver.

 

后来看了网上的花花酱大神的,https://zxi.mytechroad.com/blog/searching/leetcode-37-sudoku-solver/

DFS+ 回溯。 使用3个二维数组来保存面板的行,列,九宫格信息,这样就省去了循环调用isValid函数进行判断的过程。3ms 快得飞起啊。

 

你可能感兴趣的:(数独,算法,leetcode)