算法leetcode|37. 解数独(rust重拳出击)
Posted 二当家的白帽子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode|37. 解数独(rust重拳出击)相关的知识,希望对你有一定的参考价值。
文章目录
37. 解数独:
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 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]
是一位数字或者'.'
- 题目数据 保证 输入数独仅有一个解
分析:
- 面对这道算法题目,二当家的陷入了沉思。
- 主要是如何存储行,列,以及3*3宫内出现过的值。
- 方法很多,集合,整形数组,布尔数组都可以,只有1-9,一共9个数,最优化的空间方式应该是仅仅用一个整形,然后用位运算。
题解:
rust
impl Solution
pub fn solve_sudoku(board: &mut Vec<Vec<char>>)
let mut line = vec![vec![false; 9]; 9];
let mut column = vec![vec![false; 9]; 9];
let mut block = vec![vec![vec![false; 9]; 3]; 3];
let mut spaces = Vec::new();
(0..9).for_each(|i|
(0..9).for_each(|j|
if board[i][j] == '.'
spaces.push((i, j));
else
let digit = board[i][j].to_digit(10).unwrap() as usize - 1;
line[i][digit] = true;
column[j][digit] = true;
block[i / 3][j / 3][digit] = true;
);
);
fn dfs(board: &mut Vec<Vec<char>>, spaces: &Vec<(usize, usize)>, line: &mut Vec<Vec<bool>>, column: &mut Vec<Vec<bool>>, block: &mut Vec<Vec<Vec<bool>>>, pos: usize) -> bool
if pos == spaces.len()
return true;
let (i, j) = spaces[pos];
for digit in 0..9
if !line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]
line[i][digit] = true;
column[j][digit] = true;
block[i / 3][j / 3][digit] = true;
board[i][j] = (digit as u8 + b'1') as char;
if dfs(board, spaces, line, column, block, pos + 1)
return true;
line[i][digit] = false;
column[j][digit] = false;
block[i / 3][j / 3][digit] = false;
return false;
dfs(board, &mut spaces, &mut line, &mut column, &mut block, 0);
go
func solveSudoku(board [][]byte)
var line, column [9][9]bool
var block [3][3][9]bool
var spaces [][2]int
for i := 0; i < 9; i++
for j := 0; j < 9; j++
b := board[i][j]
if b == '.'
spaces = append(spaces, [2]inti, j)
else
digit := b - '1'
line[i][digit] = true
column[j][digit] = true
block[i/3][j/3][digit] = true
var dfs func(int) bool
dfs = func(pos int) bool
if pos == len(spaces)
return true
i, j := spaces[pos][0], spaces[pos][1]
for digit := byte(0); digit < 9; digit++
if !line[i][digit] && !column[j][digit] && !block[i/3][j/3][digit]
line[i][digit] = true
column[j][digit] = true
block[i/3][j/3][digit] = true
board[i][j] = digit + '1'
if dfs(pos + 1)
return true
line[i][digit] = false
column[j][digit] = false
block[i/3][j/3][digit] = false
return false
dfs(0)
c++
class Solution
private:
bool dfs(vector<vector<char>> &board, vector<pair<int, int>> &spaces, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos)
if (pos == spaces.size())
return true;
auto [i, j] = spaces[pos];
for (int digit = 0; digit < 9; ++digit)
if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit])
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
board[i][j] = digit + '1';
if (dfs(board, spaces, line, column, block, pos + 1))
return true;
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
return false;
public:
void solveSudoku(vector<vector<char>>& board)
bool line[9][9];
bool column[9][9];
bool block[3][3][9];
vector<pair<int, int>> spaces;
memset(line, false, sizeof(line));
memset(column, false, sizeof(column));
memset(block, false, sizeof(block));
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (board[i][j] == '.')
spaces.emplace_back(i, j);
else
int digit = board[i][j] - '1';
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
dfs(board, spaces, line, column, block, 0);
;
c
bool dfs(char **board, int *spaces[81], int spacesSize, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos)
if (pos == spacesSize)
return true;
int i = spaces[pos][0], j = spaces[pos][1];
for (int digit = 0; digit < 9; ++digit)
if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit])
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
board[i][j] = digit + '1';
if (dfs(board, spaces, spacesSize, line, column, block, pos + 1))
return true;
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
return false;
void solveSudoku(char **board, int boardSize, int *boardColSize)
bool line[9][9];
bool column[9][9];
bool block[3][3][9];
int *spaces[81];
int spacesSize = 0;
memset(line, 0, sizeof(line));
memset(column, 0, sizeof(column));
memset(block, 0, sizeof(block));
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (board[i][j] == '.')
spaces[spacesSize] = malloc(sizeof(int) * 2);
spaces[spacesSize][0] = i;
spaces[spacesSize++][1] = j;
else
int digit = board[i][j] - '1';
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
dfs(board, spaces, spacesSize, line, column, block, 0);
python
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def dfs(pos: int) -> bool:
if pos == len(spaces):
return True
i, j = spaces[pos]
for digit in range(9)以上是关于算法leetcode|37. 解数独(rust重拳出击)的主要内容,如果未能解决你的问题,请参考以下文章
算法系列之回溯算法IVleetcode51. N皇后和leetcode37. 解数独