题目描述 编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
示例 1:
输入: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”]] 输出:[ [“5”,”3”,”4”,”6”,”7”,”8”,”9”,”1”,”2”], [“6”,”7”,”2”,”1”,”9”,”5”,”3”,”4”,”8”], [“1”,”9”,”8”,”3”,”4”,”2”,”5”,”6”,”7”], [“8”,”5”,”9”,”7”,”6”,”1”,”4”,”2”,”3”], [“4”,”2”,”6”,”8”,”5”,”3”,”7”,”9”,”1”], [“7”,”1”,”3”,”9”,”2”,”4”,”8”,”5”,”6”], [“9”,”6”,”1”,”5”,”3”,”7”,”2”,”8”,”4”], [“2”,”8”,”7”,”4”,”1”,”9”,”6”,”3”,”5”], [“3”,”4”,”5”,”2”,”8”,”6”,”1”,”7”,”9”]] 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
提示:
board.length == 9
board[i].length == 9
board[i][j] 是一位数字或者 ‘.’
题目数据 保证 输入数独仅有一个解
解决方法 C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : void solveSudoku (std::vector<std::vector<char >>& board) { solve (board); } private : bool solve (std::vector<std::vector<char >>& board) { for (int i = 0 ; i < 9 ; ++i) { for (int j = 0 ; j < 9 ; ++j) { if (board[i][j] == '.' ) { for (char num = '1' ; num <= '9' ; ++num) { if (isValid (board, i, j, num)) { board[i][j] = num; if (solve (board)) { return true ; } board[i][j] = '.' ; } } return false ; } } } return true ; } bool isValid (const std::vector<std::vector<char >>& board, int row, int col, char num) { for (int i = 0 ; i < 9 ; ++i) { if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num) { return false ; } } return true ; } };
结果 执行用时 : 11 ms, 击败 67.22% 使用 C++ 的用户
内存消耗 : 7.55 MB, 击败 20.50% 使用 C++ 的用户
Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class Solution { public void solveSudoku (char [][] board) { solve(board); } private boolean solve (char [][] board) { for (int i = 0 ; i < 9 ; ++i) { for (int j = 0 ; j < 9 ; ++j) { if (board[i][j] == '.' ) { for (char num = '1' ; num <= '9' ; ++num) { if (isValid(board, i, j, num)) { board[i][j] = num; if (solve(board)) { return true ; } board[i][j] = '.' ; } } return false ; } } } return true ; } private boolean isValid (char [][] board, int row, int col, char num) { for (int i = 0 ; i < 9 ; ++i) { if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num) { return false ; } } return true ; } }
结果 执行用时 : 10 ms, 击败 14.01% 使用 Java 的用户
内存消耗 : 40.18 MB, 击败 12.93% 使用 Java 的用户
Python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution (object ): def solveSudoku (self, board ): """ :type board: List[List[str]] :rtype: None Do not return anything, modify board in-place instead. """ self .solve(board) def solve (self, board ): for i in range (9 ): for j in range (9 ): if board[i][j] == '.' : for num in map (str , range (1 , 10 )): if self .is_valid(board, i, j, num): board[i][j] = num if self .solve(board): return True board[i][j] = '.' return False return True def is_valid (self, board, row, col, num ): if num in board[row]: return False if num in [board[i][col] for i in range (9 )]: return False start_row, start_col = 3 * (row // 3 ), 3 * (col // 3 ) for i in range (3 ): for j in range (3 ): if board[start_row + i][start_col + j] == num: return False return True
结果 执行用时 : 388 ms, 击败 59.52% 使用 Python 的用户
内存消耗 : 11.52 MB, 击败 95.24% 使用 Python 的用户
Python3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution : def solveSudoku (self, board: List [List [str ]] ) -> None : """ Do not return anything, modify board in-place instead. """ self .solve(board) def solve (self, board ): for i in range (9 ): for j in range (9 ): if board[i][j] == '.' : for num in map (str , range (1 , 10 )): if self .is_valid(board, i, j, num): board[i][j] = num if self .solve(board): return True board[i][j] = '.' return False return True def is_valid (self, board, row, col, num ): if num in board[row]: return False if num in [board[i][col] for i in range (9 )]: return False start_row, start_col = 3 * (row // 3 ), 3 * (col // 3 ) for i in range (3 ): for j in range (3 ): if board[start_row + i][start_col + j] == num: return False return True
结果 执行用时 : 325 ms, 击败 42.81% 使用 Python3 的用户
内存消耗 : 16.38 MB, 击败 40.06% 使用 Python3 的用户
C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void solveSudoku (char ** board, int boardSize, int * boardColSize) { solve(board, boardSize, boardColSize); } int isValid (char ** board, int row, int col, char num, int boardSize) { for (int i = 0 ; i < boardSize; ++i) { if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num) { return 0 ; } } return 1 ; } int solve (char ** board, int boardSize, int * boardColSize) { for (int i = 0 ; i < boardSize; ++i) { for (int j = 0 ; j < *boardColSize; ++j) { if (board[i][j] == '.' ) { for (char num = '1' ; num <= '9' ; ++num) { if (isValid(board, i, j, num, boardSize)) { board[i][j] = num; if (solve(board, boardSize, boardColSize)) { return 1 ; } board[i][j] = '.' ; } } return 0 ; } } } return 1 ; }
结果 执行用时 : 19 ms, 击败 6.45% 使用 C 的用户
内存消耗 : 5.71 MB, 击败 86.69% 使用 C 的用户
C# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class Solution { public void SolveSudoku (char [][] board ) { Solve(board); } private bool Solve (char [][] board ) { for (int i = 0 ; i < 9 ; ++i) { for (int j = 0 ; j < 9 ; ++j) { if (board[i][j] == '.' ) { for (char num = '1' ; num <= '9' ; ++num) { if (IsValid(board, i, j, num)) { board[i][j] = num; if (Solve(board)) { return true ; } board[i][j] = '.' ; } } return false ; } } } return true ; } private bool IsValid (char [][] board, int row, int col, char num ) { for (int i = 0 ; i < 9 ; ++i) { if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num) { return false ; } } return true ; } }
结果 执行用时 : 128 ms, 击败 88.89% 使用 C# 的用户
内存消耗 : 46.63 MB, 击败 15.87% 使用 C# 的用户
JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const solveSudoku = (board ) => { const hasConflit = (r, c, val ) => { for (let i = 0 ; i < 9 ; i++) { if (board[i][c] == val || board[r][i] == val) { return true ; } } const subRowStart = Math .floor (r / 3 ) * 3 ; const subColStart = Math .floor (c / 3 ) * 3 ; for (let i = 0 ; i < 3 ; i++) { for (let j = 0 ; j < 3 ; j++) { if (val == board[subRowStart + i][subColStart + j]) { return true ; } } } return false ; }; const fill = (i, j ) => { if (j == 9 ) { i++; j = 0 ; if (i == 9 ) return true ; } if (board[i][j] != "." ) return fill (i, j + 1 ); for (let num = 1 ; num <= 9 ; num++) { if (hasConflit (i, j, String (num))) continue ; board[i][j] = String (num); if (fill (i, j + 1 )) return true ; board[i][j] = "." ; } return false ; }; fill (0 , 0 ); return board; };
结果 执行用时 : 78 ms, 击败 84.59% 使用 JavaScript 的用户
内存消耗 : 50.79 MB, 击败 15.41% 使用 JavaScript 的用户
TypeScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 function solveSudoku (board : string [][] ): void { const hasConflit = (r : number , c : number , val : string ): boolean => { for (let i = 0 ; i < 9 ; i++) { if (board[i][c] === val || board[r][i] === val) { return true ; } } const subRowStart = Math .floor (r / 3 ) * 3 ; const subColStart = Math .floor (c / 3 ) * 3 ; for (let i = 0 ; i < 3 ; i++) { for (let j = 0 ; j < 3 ; j++) { if (val === board[subRowStart + i][subColStart + j]) { return true ; } } } return false ; }; const fill = (i : number , j : number ): boolean => { if (j === 9 ) { i++; j = 0 ; if (i === 9 ) return true ; } if (board[i][j] !== "." ) return fill (i, j + 1 ); for (let num = 1 ; num <= 9 ; num++) { const strNum = String (num); if (!hasConflit (i, j, strNum)) { board[i][j] = strNum; if (fill (i, j + 1 )) return true ; board[i][j] = "." ; } } return false ; }; fill (0 , 0 ); }
结果 执行用时 : 82 ms, 击败 67.31% 使用 TypeScript 的用户
内存消耗 : 51.56 MB, 击败 13.46% 使用 TypeScript 的用户
PHP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Solution { function solveSudoku (&$board ) { $this ->solve ($board ); } function hasConflit ($board , $r , $c , $val ) { for ($i = 0 ; $i < 9 ; $i ++) { if ($board [$i ][$c ] === $val || $board [$r ][$i ] === $val ) { return true ; } } $subRowStart = floor ($r / 3 ) * 3 ; $subColStart = floor ($c / 3 ) * 3 ; for ($i = 0 ; $i < 3 ; $i ++) { for ($j = 0 ; $j < 3 ; $j ++) { if ($val === $board [$subRowStart + $i ][$subColStart + $j ]) { return true ; } } } return false ; } function fill (&$board , $i , $j ) { if ($j === 9 ) { $i ++; $j = 0 ; if ($i === 9 ) return true ; } if ($board [$i ][$j ] !== "." ) return $this ->fill ($board , $i , $j + 1 ); for ($num = 1 ; $num <= 9 ; $num ++) { $strNum = strval ($num ); if (!$this ->hasConflit ($board , $i , $j , $strNum )) { $board [$i ][$j ] = $strNum ; if ($this ->fill ($board , $i , $j + 1 )) return true ; $board [$i ][$j ] = "." ; } } return false ; } function solve (&$board ) { $this ->fill ($board , 0 , 0 ); } }
结果 执行用时 : 113 ms, 击败 50.00% 使用 PHP 的用户
内存消耗 : 20.03 MB, 击败 -% 使用 PHP 的用户
Swift 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class Solution { var line = Array (repeating: Set <Int >(), count: 9 ) var column = Array (repeating: Set <Int >(), count: 9 ) var block = Array (repeating: Array (repeating: Set <Int >(), count: 3 ), count: 3 ) var valid = false var spaces = [[Int ]]() func solveSudoku (_ board : inout [[Character ]]) { initializeSets(with: board) DFS (& board, 0 ) } func initializeSets (with board : [[Character ]]) { for i in 0 ..< 9 { for j in 0 ..< 9 { if board[i][j] == "." { spaces.append([i, j]) } else { let digit = Int (String (board[i][j]))! - 1 line[i].insert(digit) column[j].insert(digit) block[i/3][j/3].insert(digit) } } } } func DFS(_ board: inout [[Character]], _ pos: Int) { if pos == spaces.count { valid = true return } let space = spaces[pos] let i = space[0] let j = space[1] var digit = 0 while digit < 9 && !valid { if !line[i].contains(digit) && !column[j].contains(digit) && !block[i/3][j/3].contains(digit) { line[i].insert(digit) column[j].insert(digit) block[i/3][j/3].insert(digit) board[i][j] = Character(String(digit + 1)) DFS(&board, pos + 1) line[i].remove(digit) column[j].remove(digit) block[i/3][j/3].remove(digit) } digit += 1 } } }
结果 执行用时 : 46 ms, 击败 13.33% 使用 Swift 的用户
内存消耗 : 16.30 MB, 击败 6.67% 使用 Swift 的用户
Kotlin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { fun solveSudoku (board: Array <CharArray >) : Unit { solve(board) } private fun solve (board: Array <CharArray >) : Boolean { for (i in 0 until 9 ) { for (j in 0 until 9 ) { if (board[i][j] == '.' ) { for (num in '1' ..'9' ) { if (isValid(board, i, j, num)) { board[i][j] = num if (solve(board)) { return true } board[i][j] = '.' } } return false } } } return true } private fun isValid (board: Array <CharArray >, row: Int , col: Int , num: Char ) : Boolean { for (i in 0 until 9 ) { if (board[row][i] == num || board[i][col] == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num) { return false } } return true } }
结果 执行用时 : 149 ms, 击败 92.86% 使用 Kotlin 的用户
内存消耗 : 34.05 MB, 击败 92.86% 使用 Kotlin 的用户
Dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { void solveSudoku(List <List <String >> board) { solve(board); } bool solve(List <List <String >> board) { for (int i = 0 ; i < 9 ; ++i) { for (int j = 0 ; j < 9 ; ++j) { if (board[i][j] == '.' ) { for (int num = 1 ; num <= 9 ; ++num ) { String strNum = num .toString(); if (isValid(board, i, j, strNum)) { board[i][j] = strNum; if (solve(board)) { return true ; } board[i][j] = '.' ; } } return false ; } } } return true ; } bool isValid(List <List <String >> board, int row, int col, String num ) { for (int i = 0 ; i < 9 ; ++i) { if (board[row][i] == num || board[i][col] == num || board[3 * (row ~/ 3 ) + i ~/ 3 ][3 * (col ~/ 3 ) + i % 3 ] == num ) { return false ; } } return true ; } }
结果 执行用时 : 289 ms, 击败 100.00% 使用 Dart 的用户
内存消耗 : 145.09 MB, 击败 100.00% 使用 Dart 的用户
Go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 func solveSudoku (board [][]byte ) { solve(board) } func solve (board [][]byte ) bool { for i := 0 ; i < 9 ; i++ { for j := 0 ; j < 9 ; j++ { if board[i][j] == '.' { for num := byte ('1' ); num <= '9' ; num++ { if isValid(board, i, j, num) { board[i][j] = num if solve(board) { return true } board[i][j] = '.' } } return false } } } return true } func isValid (board [][]byte , row, col int , num byte ) bool { for i := 0 ; i < 9 ; i++ { if board[row][i] == num || board[i][col] == num || board[3 *(row/3 )+i/3 ][3 *(col/3 )+i%3 ] == num { return false } } return true }
结果 执行用时 : 3 ms, 击败 70.00% 使用 Go 的用户
内存消耗 : 1.88 MB, 击败 86.32% 使用 Go 的用户
Ruby 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 def solve_sudoku (board ) solve(board) end def solve (board ) (0 ..8 ).each do |i | (0 ..8 ).each do |j | if board[i][j] == '.' ('1' ..'9' ).each do |num | if is_valid(board, i, j, num) board[i][j] = num return true if solve(board) board[i][j] = '.' end end return false end end end true end def is_valid (board, row, col, num ) num = num.to_s (0 ..8 ).each do |i | return false if board[row][i] == num | | board[i][col] == num | | board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] == num end true end
结果 执行用时 : 548 ms, 击败 100.00% 使用 Ruby 的用户
内存消耗 : 206.85 MB, 击败 100.00% 使用 Ruby 的用户
Scala 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 object Solution { def solveSudoku (board: Array [Array [Char ]]): Unit = { solve(board) } def solve (board: Array [Array [Char ]]): Boolean = { for (i <- 0 until 9 ) { for (j <- 0 until 9 ) { if (board(i)(j) == '.') { for (num <- '1 ' to '9 ') { if (isValid(board, i, j, num)) { board(i)(j) = num if (solve(board)) { return true } board(i)(j) = '.' } } return false } } } true } def isValid (board: Array [Array [Char ]], row: Int , col: Int , num: Char ): Boolean = { for (i <- 0 until 9 ) { if (board(row)(i) == num || board(i)(col) == num || board(3 * (row / 3 ) + i / 3 )(3 * (col / 3 ) + i % 3 ) == num) { return false } } true } }
结果 执行用时 : 637 ms, 击败 80.00% 使用 Scala 的用户
内存消耗 : 56.14 MB, 击败 100.00% 使用 Scala 的用户
Rust 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 impl Solution { pub fn solve_sudoku (board: &mut Vec <Vec <char >>) { Self ::solve (board); } fn solve (board: &mut Vec <Vec <char >>) -> bool { for i in 0 ..9 { for j in 0 ..9 { if board[i][j] == '.' { for num in '1' ..='9' { if Self ::is_valid (board, i, j, num) { board[i][j] = num; if Self ::solve (board) { return true ; } board[i][j] = '.' ; } } return false ; } } } true } fn is_valid (board: &Vec <Vec <char >>, row: usize , col: usize , num: char ) -> bool { let num = num as u8 ; for i in 0 ..9 { if board[row][i] as u8 == num || board[i][col] as u8 == num || board[3 * (row / 3 ) + i / 3 ][3 * (col / 3 ) + i % 3 ] as u8 == num { return false ; } } true } }
结果 执行用时 : 6 ms, 击败 13.89% 使用 Rust 的用户
内存消耗 : 2.06 MB, 击败 75.00% 使用 Rust 的用户
Racket 暂时未解决
结果 执行用时 : ms, 击败 % 使用 Racket 的用户
内存消耗 : MB, 击败 % 使用 Racket 的用户