zoukankan      html  css  js  c++  java
  • [Swift]LeetCode37. 解数独 | Sudoku Solver

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9900641.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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.

     编写一个程序,通过已填充的空格来解决数独问题。

    一个数独的解法需遵循如下规则:

    1. 数字 1-9 在每一行只能出现一次。
    2. 数字 1-9 在每一列只能出现一次。
    3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

    空白格用 '.' 表示。

    一个数独。

    答案被标成红色。

    Note:

      • 给定的数独序列只包含数字 1-9 和字符 '.' 。
      • 你可以假设给定的数独只有唯一解。
      • 给定数独永远是 9x9 形式的。

     264ms

     1 class Solution {
     2     func solveSudoku(_ board: inout [[Character]]) {
     3         guard board.count != 0 || board[0].count != 0 else {
     4             return
     5         }
     6         helper(&board)
     7     }
     8     
     9     private func helper(_ board: inout [[Character]]) -> Bool {
    10         let m = board.count, n = board[0].count
    11     
    12         for i in 0..<m {
    13             for j in 0..<n {
    14                 if board[i][j] == "." {
    15                     for num in 1...9 {
    16                         if isValid(board, i, j, Character(String(num))) {
    17                             board[i][j] = Character(String(num))
    18                             
    19                             if helper(&board) {
    20                                 return true
    21                             } else {
    22                                 board[i][j] = "."
    23                             }
    24                         }
    25                     }
    26                     return false
    27                 }
    28             }
    29         }
    30         
    31         return true
    32     }
    33     
    34     private func isValid(_ board: [[Character]], _ i: Int, _ j: Int, _ num: Character) -> Bool {
    35         let m = board.count, n = board[0].count
    36     
    37         // check row
    38         for x in 0..<n {
    39             if board[i][x] == num {
    40                 return false
    41             }
    42         }
    43         
    44         // check col
    45         for y in 0..<m {
    46             if board[y][j] == num {
    47                 return false
    48             }
    49         }
    50         
    51         // check square
    52         for x in i / 3 * 3..<i / 3 * 3 + 3 {
    53             for y in j / 3 * 3..<j / 3 * 3 + 3 {
    54                 if board[x][y] == num {
    55                     return false
    56                 }
    57             }
    58         }
    59         
    60         return true
    61     }
    62 }

    328ms

     1 class Solution {
     2     func isValidSudoku(_ board: inout [[Character]], row: Int, column: Int, char: Character) -> Bool {
     3         for i in 0..<9 {
     4             if board[i][column] == char {
     5                 return false
     6             }
     7 
     8             if board[row][i] == char {
     9                 return false
    10             }
    11 
    12             if board[3 * (row / 3) + i / 3][3 * (column / 3) + i % 3] == char {
    13                 return false
    14             }
    15         }
    16         return true
    17     }
    18 
    19     func solve(_ board: inout [[Character]]) -> Bool {
    20         let digits: [Character] = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    21         for i in 0..<9 {
    22             for j in 0..<9 {
    23                 guard board[i][j] == "." else { continue }
    24 
    25                 for char in digits {
    26                     guard isValidSudoku(&board, row: i, column: j, char: char) else { continue }
    27 
    28                     board[i][j] = char
    29                     if solve(&board) {
    30                         return true
    31                     } else {
    32                         board[i][j] = "."
    33                     }
    34                 }
    35                 
    36                 return false
    37             }
    38         }
    39         return true
    40     }
    41 
    42     func solveSudoku(_ board: inout [[Character]]) {
    43         solve(&board)
    44     }
    45 }

    460ms

     1 class Solution {
     2     func solveSudoku(_ board: inout [[Character]]) {
     3         solve(&board)
     4     }
     5     
     6     func solve(_ board: inout [[Character]]) -> Bool{
     7         for i in 0..<9{
     8             for j in 0..<9{
     9                 if board[i][j] == "."{
    10                     for k in "123456789"{
    11                         if valid(board, i, j, k){
    12                             board[i][j] = k
    13                             if solve(&board){
    14                                 return true
    15                             }
    16                             board[i][j] = "."
    17                         }
    18                     }
    19                     return false
    20                 }
    21             }
    22         }
    23          return true
    24     }
    25     
    26     func valid(_ board: [[Character]], _ i: Int, _ j: Int, _ k: Character) -> Bool{
    27         for m in 0..<9{
    28             if board[i][m] != "." && board[i][m] == k{
    29                 return false
    30             }
    31             
    32             if board[m][j] != "." && board[m][j] == k{
    33                 return false
    34             }
    35             
    36             var rowIndex = i / 3 * 3 + m / 3
    37             var colIndex = j / 3 * 3 + m % 3
    38             if board[rowIndex][colIndex] != "." && board[rowIndex][colIndex] == k{
    39                 return false
    40             }
    41             
    42             
    43         }
    44         return true
    45     }
    46     
    47     
    48 }

    520ms

     1 class Solution {
     2     var count: Int = 0
     3     func solveSudoku(_ board: inout [[Character]]) {
     4         // var result = board
     5         solve(row: 0, col: 0, board: &board)
     6     }
     7     
     8     func solve(row: Int, col: Int, board: inout [[Character]]) -> Bool {
     9         for i in 0 ..< 9 {
    10             for j in 0 ..< 9 {
    11                 if board[i][j] == "." {
    12                     let possibilities = getPossibilities(row: i, col: j, board: board)
    13                     for current in possibilities {
    14                         count += 1
    15                         board[i][j] = current
    16                         if solve(row: i, col: j, board: &board) {
    17                             return true
    18                         } else {
    19                             board[i][j] = "."
    20                         }
    21                     }
    22                     return false
    23                 }
    24             }
    25         }
    26         return true
    27     }
    28     
    29     func getPossibilities(row: Int, col: Int, board: [[Character]]) -> [Character] {
    30         var taken : [Character] = []
    31         for i in 0 ..< 9 {
    32             if board[row][i] != "." {
    33                 taken.append(board[row][i])
    34             }
    35         }
    36         for i in 0 ..< 9 {
    37             if board[i][col] != "." {
    38                 taken.append(board[i][col])
    39             }
    40         }
    41         let cubeR = (row/3)*3
    42         let cubeC = (col/3)*3
    43         for i in cubeR ..< cubeR + 3 {
    44             for j in cubeC ..< cubeC + 3 {
    45                 if board[i][j] != "." {
    46                     taken.append(board[i][j])
    47                 }
    48             }
    49         }
    50         let all:[Character] = ["1","2","3","4","5","6","7","8","9"]
    51         var available: [Character] = []
    52         for each in all {
    53             if !taken.contains(each) {
    54                 available.append(each)
    55             }
    56         }
    57         // print("row:(row) col:(col) available:(available)")
    58         return available
    59     }
    60 }

    636ms

     1 class Solution {
     2     func solveSudoku(_ board: inout [[Character]]) {
     3         dfs(&board, 0, 0)
     4     }
     5     
     6     func dfs(_ board: inout [[Character]], _ x: Int, _ y: Int) -> Bool {
     7         if x > 8 || y > 8 {
     8             return true
     9         }
    10         
    11         if board[x][y] == "." {
    12             for k in 1...9 {
    13                 if isValid(&board, x, y, Character.init("(k)")) {
    14                     board[x][y] = Character.init("(k)")
    15                     var nextX = x
    16                     var nextY = y + 1
    17                     if nextY == 9 {
    18                         nextY = 0
    19                         nextX += 1
    20                     }
    21                     if dfs(&board, nextX, nextY) {
    22                         return true
    23                     }
    24                     board[x][y] = "."
    25                 }
    26             }
    27             return false
    28         } else {
    29             var nextX = x
    30             var nextY = y + 1
    31             if nextY == 9 {
    32                 nextY = 0
    33                 nextX += 1
    34             }
    35             return dfs(&board, nextX, nextY)
    36         }
    37     }
    38     
    39     func isValid(_ board: inout [[Character]], _ x:  Int, _ y: Int, _ k: Character) -> Bool {
    40         for i in 0..<9 {
    41             if board[i][y] == k || board[x][i] == k {
    42                 return false
    43             }
    44         }
    45         
    46         for i in 0..<3 {
    47             for j in 0..<3 {
    48                 if board[3*(x/3)+i][3*(y/3)+j] == k {
    49                     return false
    50                 }
    51             }
    52         }
    53         return true
    54     }
    55 }

    668ms

     1 class Solution {
     2   
     3   func solveSudoku(_ board: inout [[Character]]) {
     4     
     5     solveSudoku2(&board)
     6   }
     7     
     8   func solveSudoku2(_ board: inout [[Character]]) -> Bool {
     9     for i in 0 ..< board.count {
    10       for j in 0 ..< board[0].count {
    11         if board[i][j] == "." {
    12           
    13           
    14           for n in ["1", "2", "3", "4", "5", "6", "7", "8", "9"] {
    15             var tempBoard = board
    16             if canPlace(board, Character(n), i, j) {
    17               tempBoard[i][j] = Character(n)
    18               
    19               if isSolved(tempBoard) {
    20                 board = tempBoard
    21                 return true
    22               } else {
    23                 if solveSudoku2(&tempBoard) {
    24                   board = tempBoard
    25                   return true
    26                 }
    27               }
    28             }
    29           }
    30           
    31           return false
    32         }
    33       }
    34     }
    35     
    36     return true
    37   }
    38   
    39   
    40   func canPlace(_ board: [[Character]], _ ch: Character, _ i: Int, _ j: Int) -> Bool {
    41     if board[i].contains(ch) {
    42       return false
    43     }
    44     
    45     for ii in 0 ..< board.count {
    46       if board[ii][j] == ch {
    47         return false
    48       }
    49     }
    50     
    51     var iMax = 3
    52     
    53     if i <= 2 {
    54       iMax = 3
    55     } else if i <= 5 {
    56       iMax = 6
    57     } else {
    58       iMax = 9
    59     }
    60     
    61     var jMax = 3
    62     
    63     if j <= 2 {
    64       jMax = 3
    65     } else if j <= 5 {
    66       jMax = 6
    67     } else {
    68       jMax = 9
    69     }
    70     
    71     for ii in iMax - 3 ..< iMax {
    72       for jj in jMax - 3 ..< jMax {
    73         if board[ii][jj] == ch {
    74           return false
    75         }
    76       }
    77     }
    78     
    79     return true
    80   }
    81   
    82   func isSolved(_ board: [[Character]]) -> Bool {
    83     for i in 0 ..< board.count {
    84       for j in 0 ..< board[0].count {
    85         if board[i][j] == "." {
    86           return false
    87         }
    88       }
    89     }
    90     
    91     return true
    92   }
    93 }

    692ms

     1 class Solution {
     2     func solveSudoku(_ board: inout [[Character]]) {
     3         guard board.count != 0 || board[0].count != 0 else {
     4             return
     5         }
     6         helper(&board)
     7     }
     8     
     9     private func helper(_ board: inout [[Character]]) -> Bool {
    10         let m = board.count, n = board[0].count
    11     
    12         for i in 0..<m {
    13             for j in 0..<n {
    14                 if board[i][j] == "." {
    15                     for num in 1...9 {
    16                         if isValid(board, i, j, Character(String(num))) {
    17                             board[i][j] = Character(String(num))
    18                             
    19                             if helper(&board) {
    20                                 return true
    21                             } else {
    22                                 board[i][j] = "."
    23                             }
    24                         }
    25                     }
    26                     return false
    27                 }
    28             }
    29         }
    30         
    31         return true
    32     }
    33     
    34     private func isValid(_ board: [[Character]], _ i: Int, _ j: Int, _ num: Character) -> Bool {
    35         let m = board.count, n = board[0].count
    36     
    37         // check row
    38         for x in 0..<n {
    39             if board[i][x] == num {
    40                 return false
    41             }
    42         }
    43         
    44         // check col
    45         for y in 0..<m {
    46             if board[y][j] == num {
    47                 return false
    48             }
    49         }
    50         
    51         // check square
    52         for x in i / 3 * 3..<i / 3 * 3 + 3 {
    53             for y in j / 3 * 3..<j / 3 * 3 + 3 {
    54                 if board[x][y] == num {
    55                     return false
    56                 }
    57             }
    58         }
    59         
    60         return true
    61     }
    62 }
  • 相关阅读:
    hgoi#20191101
    hgoi#20191031
    hgoi#20191030
    hgoi#20191029-2
    RMQ (Range Minimum/Maximum Query)
    数学浅谈-组合数与数学期望
    重庆NK十日行-知识点汇总
    分块
    STL—algorithm与Map容器
    搜索—迭代加深
  • 原文地址:https://www.cnblogs.com/strengthen/p/9900641.html
Copyright © 2011-2022 走看看