Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eb3c23f

Browse files
author
Zhang Xiaodong
committed
solve 37
1 parent efdbe91 commit eb3c23f

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

src/solution/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ mod s0033_search_in_rotated_sorted_array;
3232
mod s0034_find_first_and_last_position_of_element_in_sorted_array;
3333
mod s0035_search_insert_position;
3434
mod s0036_valid_sudoku;
35+
mod s0037_sudoku_solver;

src/solution/s0037_sudoku_solver.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* [37] 解数独
3+
*
4+
* 编写一个程序,通过填充空格来解决数独问题。
5+
* 数独的解法需 遵循如下规则:
6+
* <ol>
7+
* 数字 1-9 在每一行只能出现一次。
8+
* 数字 1-9 在每一列只能出现一次。
9+
* 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
10+
* </ol>
11+
* 数独部分空格内已填入了数字,空白格用 '.' 表示。
12+
*
13+
* <div class="top-view__1vxA">
14+
* <div class="original__bRMd">
15+
* <div>
16+
* 示例 1:
17+
* <img src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2021/04/12/250px-sudoku-by-l2g-20050714svg.png" style="height:250px; width:250px" />
18+
* 输入: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"]]
19+
* 输出:[["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"]]
20+
* 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
21+
* <img src=" https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2021/04/12/250px-sudoku-by-l2g-20050714_solutionsvg.png" style="height:250px; width:250px" />
22+
*
23+
*
24+
* 提示:
25+
*
26+
* board.length == 9
27+
* board[i].length == 9
28+
* board[i][j] 是一位数字或者 '.'
29+
* 题目数据 保证 输入数独仅有一个解
30+
* </div>
31+
* </div>
32+
* </div>
33+
*
34+
*/
35+
pub struct Solution {}
36+
37+
// problem: https://leetcode.cn/problems/sudoku-solver/
38+
// discuss: https://leetcode.cn/problems/sudoku-solver/discuss/?currentPage=1&orderBy=most_votes&query=
39+
40+
// submission codes start here
41+
42+
use std::collections::HashSet;
43+
44+
impl Solution {
45+
fn init_sets(board: &mut Vec<Vec<char>>) -> (Vec<HashSet<char>>, Vec<HashSet<char>>, Vec<HashSet<char>>) {
46+
let (mut rows, mut cols, mut blks) = (vec![], vec![], vec![]);
47+
for j in 0..9 {
48+
let mut row = HashSet::new();
49+
let mut col = HashSet::new();
50+
let mut blk = HashSet::new();
51+
rows.push(row);
52+
cols.push(col);
53+
blks.push(blk);
54+
}
55+
for i in 0..81 {
56+
let (m, n) = (i/9, i%9);
57+
let blk_idx = m / 3 * 3 + n / 3;
58+
match board[m][n] {
59+
'.' => {},
60+
c => {
61+
cols[n].insert(c);
62+
rows[m].insert(c);
63+
blks[blk_idx].insert(c);
64+
},
65+
}
66+
}
67+
return (rows, cols, blks);
68+
}
69+
70+
pub fn solve_sudoku(board: &mut Vec<Vec<char>>) {
71+
let (mut rows, mut cols, mut blks) = Self::init_sets(board);
72+
let mut stack = vec![];
73+
let mut i = 0;
74+
let mut sc = '1';
75+
76+
'outer: while i < 81 {
77+
let (m, n) = (i/9, i%9);
78+
let blk_idx = m / 3 * 3 + n / 3;
79+
match board[m][n] {
80+
'.' => {
81+
let mut found = false;
82+
for c in sc..='9' {
83+
if rows[m].contains(&c) || cols[n].contains(&c) || blks[blk_idx].contains(&c) {
84+
continue;
85+
}
86+
board[m][n] = c;
87+
88+
rows[m].insert(c);
89+
cols[n].insert(c);
90+
blks[blk_idx].insert(c);
91+
92+
stack.push((i, c));
93+
found = true;
94+
break;
95+
}
96+
if !found {
97+
(i, sc) = stack.pop().unwrap();
98+
let (m, n) = (i/9, i%9);
99+
let blk_idx = m / 3 * 3 + n / 3;
100+
board[m][n] = '.';
101+
rows[m].remove(&sc);
102+
cols[n].remove(&sc);
103+
blks[blk_idx].remove(&sc);
104+
sc = (sc as u8 + 1) as char;
105+
continue 'outer;
106+
}
107+
},
108+
_ => {},
109+
}
110+
sc = '1';
111+
i += 1;
112+
}
113+
}
114+
}
115+
116+
// submission codes end
117+
118+
#[cfg(test)]
119+
mod tests {
120+
use super::*;
121+
122+
#[test]
123+
fn test_37() {
124+
let mut board = vec![
125+
vec!['5','3','.','.','7','.','.','.','.'],
126+
vec!['6','.','.','1','9','5','.','.','.'],
127+
vec!['.','9','8','.','.','.','.','6','.'],
128+
vec!['8','.','.','.','6','.','.','.','3'],
129+
vec!['4','.','.','8','.','3','.','.','1'],
130+
vec!['7','.','.','.','2','.','.','.','6'],
131+
vec!['.','6','.','.','.','.','2','8','.'],
132+
vec!['.','.','.','4','1','9','.','.','5'],
133+
vec!['.','.','.','.','8','.','.','7','9'],
134+
];
135+
Solution::solve_sudoku(&mut board);
136+
assert_eq!(board, vec![
137+
vec!['5','3','4','6','7','8','9','1','2'],
138+
vec!['6','7','2','1','9','5','3','4','8'],
139+
vec!['1','9','8','3','4','2','5','6','7'],
140+
vec!['8','5','9','7','6','1','4','2','3'],
141+
vec!['4','2','6','8','5','3','7','9','1'],
142+
vec!['7','1','3','9','2','4','8','5','6'],
143+
vec!['9','6','1','5','3','7','2','8','4'],
144+
vec!['2','8','7','4','1','9','6','3','5'],
145+
vec!['3','4','5','2','8','6','1','7','9'],
146+
]);
147+
}
148+
}

0 commit comments

Comments
 (0)