Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
Each of the digits 1-9 must occur exactly once in each row. Each of the digits 1-9 must occur exactly once in each column. 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 ‘.’.
A sudoku puzzle…
…and its solution numbers marked in red.
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.
Solution:
For this question, we can use recursive/backtracking to solve it.
Find a '.' location that need to fill in a number
Check if this position can be filled in with some number. The checking can be done by scanning the same row, the same column, the same 3*3 box.
If we can fill the position with a number, then we use recursive to find next '.' position to be filled. One thing to notice is that, when we do the recursive, we might found out that this current result is false. At this time, we can use backtracking to previous level, and try to put other number in the previous position.
classSolution: defsolveSudoku(self, board: List[List[str]]) -> None: defisValid(board, row, col, x): if any(board[row][j] == x for j in range(9)): returnFalse # Check col if any(board[i][col] == x for i in range(9)): returnFalse # Check block br, bc = 3*(row//3), 3*(col//3) if any(board[i][j] == x for i in range(br, br+3) for j in range(bc, bc+3)): returnFalse returnTrue defsolve(board, r, c): while board[r][c] != '.': c += 1 if c == 9: c, r = 0, r+1 if r == 9: returnTrue # Try all options, backtracking if not work for k in"123456789": if isValid(board, r, c, k): board[r][c] = str(k) if solve(board, r, c): returnTrue board[r][c] = '.' returnFalse solve(board, 0, 0)
classSolution { public: voidsolveSudoku(vector<vector<char>>& board){ /* 1. find location, '.', to check 2. determine what number can this position use. By checking whether if same row || same column || same box, have this number. 3. after filling this position, we can pass this board to the recursive and check next '.' to be filled. */ if(board.empty() || board[0].size() == 0) return; solve(board); } boolsolve(vector<vector<char>>& board){ for(int i= 0; i< board.size(); i++){ for(int j= 0; j< board[0].size(); j++){ if(board[i][j]== '.'){ //a location needs to be filled for(char c= '1'; c<= '9'; c++){ //try from 1 through 9 if(isValid(board, i, j, c)){ //check if this 'c' can put in the position board[i][j]= c; //put c into the location if(solve(board)) //if this is the solution returntrue; else board[i][j]= '.'; //go back and try another char } } returnfalse; } } } returntrue; } boolisValid(vector<vector<char>>& board, int row, int col, char c){ for(int i= 0; i< 9; i++){ if(board[i][col] != '.' && board[i][col]== c) returnfalse; //check row by row, found c is already used if(board[row][i] != '.' && board[row][i]== c) returnfalse; int boxR= 3*(row/3)+ i/3; int boxC= 3*(col/3)+ i%3; if(board[boxR][boxC] != '.' && board[boxR][boxC]== c) returnfalse; } returntrue; } };