-
Notifications
You must be signed in to change notification settings - Fork 4
/
36.Valid_Sudoku.js
138 lines (138 loc) · 3.6 KB
/
36.Valid_Sudoku.js
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* @param {character[][]} board
* @return {boolean}
*/
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function (board) {
/**
* 解法1:HashMap (3*3检测小学生版)
*/
const columnMap = new Map();
const subMap = new Map();
for (let i = 0; i < board.length; i++) {
const rowMap = new Map();
for (let j = 0; j < board[i].length; j++) {
// 数字 1-9 在每一行只能出现一次。
if (board[i][j] === ".") {
continue;
}
if (rowMap.has(board[i][j])) {
return false;
} else {
rowMap.set(board[i][j], true);
}
// 数字 1-9 在每一列只能出现一次。
if (columnMap.has(j)) {
if (columnMap.get(j).indexOf(board[i][j]) !== -1) {
return false;
} else {
const arr = columnMap.get(j);
arr.push(board[i][j]);
columnMap.set(j, arr);
}
} else {
columnMap.set(j, [board[i][j]]);
}
// 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
if (!check(0, 2, 1, i, j)) {
return false;
}
if (!check(3, 5, 4, i, j)) {
return false;
}
if (!check(6, 8, 7, i, j)) {
return false;
}
}
}
return true;
/**
* 将x轴方向表示列的j分为3段
* 将y轴方向表示行的i分为3段
* 分为1~9 9个区域
*/
function check(startI, endI, boxIndex, i, j) {
if (i >= startI && i <= endI) {
if (j >= 0 && j <= 2) {
if (!checkMap(i, j, boxIndex)) {
return false;
}
}
if (j >= 3 && j <= 5) {
if (!checkMap(i, j, boxIndex + 1)) {
return false;
}
}
if (j >= 6 && j <= 8) {
if (!checkMap(i, j, boxIndex + 2)) {
return false;
}
}
}
return true;
}
// 通过map检测一个3*3区域中是否有重复项
function checkMap(i, j, boxIndex) {
if (subMap.has(boxIndex)) {
if (subMap.get(boxIndex).indexOf(board[i][j]) !== -1) {
return false;
} else {
const arr = subMap.get(boxIndex);
arr.push(board[i][j]);
subMap.set(boxIndex, arr);
}
} else {
subMap.set(boxIndex, [board[i][j]]);
}
return true;
}
/**
* 解法2: HashMap (3*3检测优化版)
*/
const columnMap = new Map();
const subMap = new Map();
for (let i = 0; i < board.length; i++) {
const rowMap = new Map();
for (let j = 0; j < board[i].length; j++) {
// 数字 1-9 在每一行只能出现一次。
if (board[i][j] === ".") {
continue;
}
if (rowMap.has(board[i][j])) {
return false;
} else {
rowMap.set(board[i][j], true);
}
// 数字 1-9 在每一列只能出现一次。
if (columnMap.has(j)) {
if (columnMap.get(j).indexOf(board[i][j]) !== -1) {
return false;
} else {
const arr = columnMap.get(j);
arr.push(board[i][j]);
columnMap.set(j, arr);
}
} else {
columnMap.set(j, [board[i][j]]);
}
// 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
// 0,1,2 0,3,6=> 0~8
const boxIndex = Math.floor(j / 3) + Math.floor(i / 3) * 3;
if (subMap.has(boxIndex)) {
if (subMap.get(boxIndex).indexOf(board[i][j]) !== -1) {
return false;
} else {
const arr = subMap.get(boxIndex);
arr.push(board[i][j]);
subMap.set(boxIndex, arr);
}
} else {
subMap.set(boxIndex, [board[i][j]]);
}
}
}
return true;
};