Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4211da8

Browse files
feat: add weekly contest 465 (#4680)
1 parent f361e24 commit 4211da8

File tree

18 files changed

+1289
-567
lines changed

18 files changed

+1289
-567
lines changed

‎solution/0000-0099/0037.Sudoku Solver/README.md

Lines changed: 67 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@ tags:
6868

6969
### 方法一:回溯
7070

71-
我们用数组 `row``col``box` 分别记录每一行、每一列、每个 3x3 宫格中数字是否出现过。如果数字 `i` 在第 `r` 行、第 `c` 列、第 `b` 个 3x3 宫格中出现过,那么 `row[r][i]``col[c][i]``box[b][i]` 都为 `true`
71+
我们用数组 $\textit{row},ドル $\textit{col},ドル $\textit{box}$ 分别记录每一行、每一列、每个 3x3 宫格中数字是否出现过。如果数字 $i$ 在第 $r$ 行、第 $c$ 列、第 $b$ 个 3x3 宫格中出现过,那么 $\text{row[r][i]},ドル $\text{col[c][i]},ドル $\text{box[b][i]}$ 都为 $true$
7272

73-
我们遍历 `board` 的每一个空格,枚举它可以填入的数字 `v`,如果 `v` 在当前行、当前列、当前 3x3 宫格中没有出现过,那么我们就可以尝试填入数字 `v`,并继续搜索下一个空格。如果搜索到最后,所有空格填充完毕,那么就说明找到了一个可行解。
74-
75-
时间复杂度 $O(9^{81}),ドル空间复杂度 $O(9^2)$。
73+
我们遍历 $\textit{board}$ 中的每一个空格,枚举它可以填入的数字 $v,ドル如果 $v$ 在当前行、当前列、当前 3x3 宫格中没有出现过,那么我们就可以尝试填入数字 $v,ドル并继续搜索下一个空格。如果搜索到最后,所有空格填充完毕,那么就说明找到了一个可行解。
7674

7775
<!-- tabs:start -->
7876

@@ -161,16 +159,14 @@ class Solution {
161159
#### C++
162160

163161
```cpp
164-
using pii = pair<int, int>;
165-
166162
class Solution {
167163
public:
168164
void solveSudoku(vector<vector<char>>& board) {
169165
bool row[9][9] = {false};
170166
bool col[9][9] = {false};
171167
bool block[3][3][9] = {false};
172168
bool ok = false;
173-
vector<pii> t;
169+
vector<pair<int, int>> t;
174170
for (int i = 0; i < 9; ++i) {
175171
for (int j = 0; j < 9; ++j) {
176172
if (board[i][j] == '.') {
@@ -181,7 +177,7 @@ public:
181177
}
182178
}
183179
}
184-
function<void(int k)> dfs = [&](int k) {
180+
auto dfs = [&](this auto&& dfs, int k) -> void {
185181
if (k == t.size()) {
186182
ok = true;
187183
return;
@@ -250,133 +246,41 @@ func solveSudoku(board [][]byte) {
250246
```cs
251247
public class Solution {
252248
public void SolveSudoku(char[][] board) {
253-
this.board = new ushort?[9,9];
254-
for (var i = 0; i < 9; ++i)
255-
{
256-
for (var j = 0; j < 9; ++j)
257-
{
258-
if (board[i][j] != '.')
259-
{
260-
this.board[i, j] = (ushort) (1 << (board[i][j] - '0' - 1));
261-
}
262-
}
263-
}
249+
bool[,] row = new bool[9, 9];
250+
bool[,] col = new bool[9, 9];
251+
bool[,,] block = new bool[3, 3, 9];
252+
bool ok = false;
253+
var t = new List<(int, int)>();
264254

265-
if (SolveSudoku(0, 0))
266-
{
267-
for (var i = 0; i < 9; ++i)
268-
{
269-
for (var j = 0; j < 9; ++j)
270-
{
271-
if (board[i][j] == '.')
272-
{
273-
board[i][j] = '0';
274-
while (this.board[i, j].Value != 0)
275-
{
276-
board[i][j] = (char)(board[i][j] + 1);
277-
this.board[i, j] >>= 1;
278-
}
279-
}
255+
for (int i = 0; i < 9; ++i) {
256+
for (int j = 0; j < 9; ++j) {
257+
if (board[i][j] == '.') {
258+
t.Add((i, j));
259+
} else {
260+
int v = board[i][j] - '1';
261+
row[i, v] = col[j, v] = block[i / 3, j / 3, v] = true;
280262
}
281263
}
282264
}
283-
}
284265

285-
private ushort?[,] board;
286-
287-
private bool ValidateHorizontalRule(int row)
288-
{
289-
ushort temp = 0;
290-
for (var i = 0; i < 9; ++i)
291-
{
292-
if (board[row, i].HasValue)
293-
{
294-
if ((temp | board[row, i].Value) == temp)
295-
{
296-
return false;
297-
}
298-
temp |= board[row, i].Value;
299-
}
300-
}
301-
return true;
302-
}
303-
304-
private bool ValidateVerticalRule(int column)
305-
{
306-
ushort temp = 0;
307-
for (var i = 0; i < 9; ++i)
308-
{
309-
if (board[i, column].HasValue)
310-
{
311-
if ((temp | board[i, column].Value) == temp)
312-
{
313-
return false;
314-
}
315-
temp |= board[i, column].Value;
266+
void Dfs(int k) {
267+
if (k == t.Count) {
268+
ok = true;
269+
return;
316270
}
317-
}
318-
return true;
319-
}
320-
321-
private bool ValidateBlockRule(int row, int column)
322-
{
323-
var startRow = row / 3 * 3;
324-
var startColumn = column / 3 * 3;
325-
ushort temp = 0;
326-
for (var i = startRow; i < startRow + 3; ++i)
327-
{
328-
for (var j = startColumn; j < startColumn + 3; ++j)
329-
{
330-
if (board[i, j].HasValue)
331-
{
332-
if ((temp | board[i, j].Value) == temp)
333-
{
334-
return false;
335-
}
336-
temp |= board[i, j].Value;
271+
var (i, j) = t[k];
272+
for (int v = 0; v < 9; ++v) {
273+
if (!row[i, v] && !col[j, v] && !block[i / 3, j / 3, v]) {
274+
row[i, v] = col[j, v] = block[i / 3, j / 3, v] = true;
275+
board[i][j] = (char)(v + '1');
276+
Dfs(k + 1);
277+
if (ok) return;
278+
row[i, v] = col[j, v] = block[i / 3, j / 3, v] = false;
337279
}
338280
}
339281
}
340-
return true;
341-
}
342-
343-
private bool SolveSudoku(int i, int j)
344-
{
345-
while (true)
346-
{
347-
if (j == 9)
348-
{
349-
++i;
350-
j = 0;
351-
}
352-
if (i == 9)
353-
{
354-
return true;
355-
}
356-
if (board[i, j].HasValue)
357-
{
358-
++j;
359-
}
360-
else
361-
{
362-
break;
363-
}
364-
}
365282

366-
ushort stop = 1 << 9;
367-
for (ushort t = 1; t != stop; t <<= 1)
368-
{
369-
board[i, j] = t;
370-
if (ValidateHorizontalRule(i) && ValidateVerticalRule(j) && ValidateBlockRule(i, j))
371-
{
372-
if (SolveSudoku(i, j + 1))
373-
{
374-
return true;
375-
}
376-
}
377-
}
378-
board[i, j] = null;
379-
return false;
283+
Dfs(0);
380284
}
381285
}
382286
```
@@ -386,78 +290,52 @@ public class Solution {
386290
```php
387291
class Solution {
388292
/**
389-
* @param string[][] $board
390-
* @return bool
293+
* @param String[][] $board
294+
* @return NULL
391295
*/
392-
393-
public function solveSudoku(&$board) {
394-
if (isSolved($board)) {
395-
return true;
396-
}
397-
398-
$emptyCell = findEmptyCell($board);
399-
$row = $emptyCell[0];
400-
$col = $emptyCell[1];
401-
402-
for ($num = 1; $num <= 9; $num++) {
403-
if (isValid($board, $row, $col, $num)) {
404-
$board[$row][$col] = (string) $num;
405-
if ($this->solveSudoku($board)) {
406-
return true;
296+
function solveSudoku(&$board) {
297+
$row = array_fill(0, 9, array_fill(0, 9, false));
298+
$col = array_fill(0, 9, array_fill(0, 9, false));
299+
$block = array_fill(0, 3, array_fill(0, 3, array_fill(0, 9, false)));
300+
$ok = false;
301+
$t = [];
302+
303+
for ($i = 0; $i < 9; ++$i) {
304+
for ($j = 0; $j < 9; ++$j) {
305+
if ($board[$i][$j] === '.') {
306+
$t[] = [$i, $j];
307+
} else {
308+
$v = ord($board[$i][$j]) - ord('1');
309+
$row[$i][$v] = true;
310+
$col[$j][$v] = true;
311+
$block[intval($i / 3)][intval($j / 3)][$v] = true;
407312
}
408-
$board[$row][$col] = '.';
409313
}
410314
}
411-
return false;
412-
}
413-
}
414-
415-
function isSolved($board) {
416-
foreach ($board as $row) {
417-
if (in_array('.', $row)) {
418-
return false;
419-
}
420-
}
421-
return true;
422-
}
423315

424-
function findEmptyCell($board) {
425-
for ($row = 0; $row < 9; $row++) {
426-
for ($col = 0; $col < 9; $col++) {
427-
if ($board[$row][$col] === '.') {
428-
return [$row, $col];
316+
$dfs = function ($k) use (&$dfs, &$board, &$row, &$col, &$block, &$ok, &$t) {
317+
if ($k === count($t)) {
318+
$ok = true;
319+
return;
429320
}
430-
}
431-
}
432-
433-
return null;
434-
}
435-
436-
function isValid($board, $row, $col, $num) {
437-
for ($i = 0; $i < 9; $i++) {
438-
if ($board[$row][$i] == $num) {
439-
return false;
440-
}
441-
}
442-
443-
for ($i = 0; $i < 9; $i++) {
444-
if ($board[$i][$col] == $num) {
445-
return false;
446-
}
447-
}
448-
449-
$startRow = floor($row / 3) * 3;
450-
$endCol = floor($col / 3) * 3;
451-
452-
for ($i = 0; $i < 3; $i++) {
453-
for ($j = 0; $j < 3; $j++) {
454-
if ($board[$startRow + $i][$endCol + $j] == $num) {
455-
return false;
321+
[$i, $j] = $t[$k];
322+
for ($v = 0; $v < 9; ++$v) {
323+
if (!$row[$i][$v] && !$col[$j][$v] && !$block[intval($i / 3)][intval($j / 3)][$v]) {
324+
$row[$i][$v] = $col[$j][$v] = $block[intval($i / 3)][intval($j / 3)][$v] = true;
325+
$board[$i][$j] = chr($v + ord('1'));
326+
$dfs($k + 1);
327+
if ($ok) {
328+
return;
329+
}
330+
$row[$i][$v] = $col[$j][$v] = $block[intval($i / 3)][intval($j / 3)][
331+
$v
332+
] = false;
333+
}
456334
}
457-
}
458-
}
335+
};
459336

460-
return true;
337+
$dfs(0);
338+
}
461339
}
462340
```
463341

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /