zoukankan      html  css  js  c++  java
  • LeetCode 37. Sudoku Solver

    原题链接在此:https://leetcode.com/problems/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 '.'.


    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.

    题解:

    DFS needs state of board and current index.

    DFS return value needs to indicate if we could fill the whole board.

    For the current index, if if is '.', fill it with '1' to '9' and if it is valid, continue with next cell. If next cell return value is true, then we need to stop here, no backtracking, return true.

    If it is not '.', then it is digit, return next one.

    DFS returns boolean. This is a technique. When there is a valid answer, stop the DFS. Then DFS could return boolean and check if(DFS) then return to stop DFS.

    Note: 1. 递归时当j == board[0].length 时, 应该是 return helper, 而不是单单的helper, 若是没有return, 会继续向下运行,到20行时就会out of index.

      2. 检查完isValid后直接检查是否继续递归是否有一个solution, 若是有就应该停下return.

    Time Complexity: exponential.

    Space: 递归最多会用O(board.length ^ 2)层stack.

    AC Java: 

     1 class Solution {
     2     public void solveSudoku(char[][] board) {
     3         if(board == null || board.length != 9 || board[0].length != 9){
     4             return;
     5         }
     6         
     7         dfsSolve(board, 0, 0);
     8     }
     9     
    10     private boolean dfsSolve(char [][] board, int i, int j){
    11         if(i == board.length){
    12             return true;
    13         }
    14         
    15         if(j == board[0].length){
    16             // get to next row
    17             return dfsSolve(board, i+1, 0);
    18         }
    19         
    20         if(board[i][j] == '.'){
    21             for(char c = '1'; c<='9'; c++){
    22                 board[i][j] = c;
    23                 if(isValid(board, i, j)){
    24                     // check if there is a solution, 如果这里有一个正确的solution就应该停下了
    25                     if(dfsSolve(board, i, j+1)){
    26                         return true;
    27                     }
    28                 }
    29             }
    30             
    31             board[i][j] = '.';
    32         }else{
    33             // 这里已有数字,直接填本行下一个
    34             return dfsSolve(board, i, j+1);
    35         }
    36         
    37         return false;
    38     }
    39     
    40     private boolean isValid(char [][] board, int x, int y){
    41         for(int i = 0; i<9; i++){
    42             if(i != x && board[i][y] == board[x][y]){
    43                 return false;
    44             }
    45         }
    46         
    47         for(int j = 0; j<9; j++){
    48             if(j != y && board[x][j] == board[x][y]){
    49                 return false;
    50             }
    51         }
    52         
    53         int boxR = x / 3 * 3;
    54         int boxC = y / 3 * 3;
    55         for(int i = boxR; i < boxR + 3; i++){
    56             for(int j = boxC; j < boxC + 3; j++){
    57                 if(i == x && j == y){
    58                     continue;
    59                 }
    60                 
    61                 if(board[i][j] == board[x][y]){
    62                     return false;
    63                 }
    64             }
    65         }
    66         
    67         return true;
    68     }
    69 }

    AC Python:

     1 class Solution:
     2     def solveSudoku(self, board: List[List[str]]) -> None:
     3         self.dfs(board, 0, 0)
     4     
     5     def dfs(self, board: List[List[str]], i: int, j: int) -> bool:
     6         if i == 9:
     7             return True
     8         
     9         if j == 9:
    10             return self.dfs(board, i + 1, 0)
    11         
    12         if board[i][j] == '.':
    13             for c in range(1, 10):
    14                 board[i][j] = str(c)
    15                 if self.isValid(board, i, j):
    16                     if self.dfs(board, i, j + 1):
    17                         return True
    18             
    19             board[i][j] = '.'
    20         else:
    21             return self.dfs(board, i, j + 1)
    22         
    23         return False
    24     
    25     def isValid(self, board: List[List[str]], x: int, y: int) -> bool:
    26         for i in range(0, 9):            
    27             if i != x and board[i][y] == board[x][y]:
    28                 return False
    29             
    30         for j in range(0, 9):
    31             if j != y and board[x][j] == board[x][y]:
    32                 return False
    33             
    34         boxX = x // 3 * 3
    35         boxY = y // 3 * 3
    36         for i in range(boxX, boxX + 3):
    37             for j in range(boxY, boxY + 3):
    38                 if i == x and j == y:
    39                     continue
    40                 
    41                 if board[i][j] == board[x][y]:
    42                     return False
    43                 
    44         return True

    类似Valid SudokuUnique Paths III.

  • 相关阅读:
    【机器学习】sklearn之生成三类数据用于聚类,python
    【机器学习】sklearn之生成环形和半环型数据,python
    【机器学习】sklearn之创建数据集,python
    【python】使用plotly画三维立体高逼格图,数据可视化
    【python】使用jieba中的textrank提取文本/文章关键词,超简单!
    【python】使用jieba提取文本关键词,超简单!
    【机器学习】gensim.models.Word2Vec()参数的详细解释,python
    XP系统老电脑如何安装Linux系统
    PHP中派生是什么?
    MySQL中CURD是什么?
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4825061.html
Copyright © 2011-2022 走看看