为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode37. 解数独 | Sudoku Solver

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

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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 }

 

posted @ 2018-11-03 14:11  为敢技术  阅读(728)  评论(0编辑  收藏  举报