-
Notifications
You must be signed in to change notification settings - Fork 71
/
No36.valid-sudoku.js
160 lines (138 loc) · 3.95 KB
/
No36.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
* Difficulty:
* Medium
*
* Desc:
* Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules: http://sudoku.com.au/TheRules.aspx
* The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
*
* 检查数独棋盘上的数字是否合法。还没有填充的数字用 '.' 表示
* 注意:
* 输入为 9 * 9 的数组
* [
* [".", ".", ".", ".", "5", ".", ".", "1", "."],
* [".", "4", ".", "3", ".", ".", ".", ".", "."],
* [".", ".", ".", ".", ".", "3", ".", ".", "1"],
* ["8", ".", ".", ".", ".", ".", ".", "2", "."],
* [".", ".", "2", ".", "7", ".", ".", ".", "."],
* [".", "1", "5", ".", ".", ".", ".", ".", "."],
* [".", ".", ".", ".", ".", "2", ".", ".", "."],
* [".", "2", ".", "9", ".", ".", ".", ".", "."],
* [".", ".", "4", ".", ".", ".", ".", ".", "."]
* ]
* 其中,从 (0, 0) 到 (2, 2) 的 3 * 3 方格内表示宫1,并可由此类推
*/
/**
* 利用数组规则,检查每行、每列、每宫内的数字是否合法(不能有重复)
*/
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
var data = {};
var boxData = {};
var validate = true;
for (var i = 0; i < board.length; i += 1) {
var box = board[i];
var rowId = `r${i + 1}`;
var boxRow = Math.floor(i / 3) + 1;
var numbers = box.filter(item => item !== '.');
if (new Set(numbers).size < numbers.length) {
validate = false;
break;
}
for (var j = 0; j < box.length; j += 1) {
var columnId = `c${j + 1}`;
var boxColumn = Math.floor(j / 3) + 1;
var boxId = `b${(boxRow - 1) * 3 + boxColumn}`;
if (!data[columnId]) {
data[columnId] = new Set();
}
if (!data[rowId]) {
data[rowId] = new Set();
}
var num = box[j];
if (num === '.') continue;
if (data[columnId].has(num) || data[rowId].has(num)) {
validate = false;
break;
}
data[columnId].add(num);
data[rowId].add(num);
if (!boxData[boxId]) {
boxData[boxId] = [];
}
boxData[boxId].push(num);
}
if (!validate) break;
}
if (!validate) return validate;
for (var i = 0; i < Object.keys(boxData).length; i += 1) {
var box = boxData[Object.keys(boxData)[i]];
if (box.length > new Set(box).size) {
validate = false;
break;
}
}
return validate;
};
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
let bi = 0
let bj = 0
const map = {
row: {},
column: {}
}
const checkValidate = (i, j) => {
const set = new Set()
for (let row = i; row < i + 3; row += 1) {
if (map.row[row] === undefined) {
const nums = board[row].filter(n => n !== '.')
map.row[row] = new Set(nums).size === nums.length
}
if (!map.row[row]) return false
for (let column = j; column < j + 3; column += 1) {
if (board[row][column] !== '.') {
if (!map.column[column]) map.column[column] = []
map.column[column].push(board[row][column])
if (set.has(board[row][column])) return false
set.add(board[row][column])
}
}
}
return true
}
while (bi <= 2 && bj <= 2) {
const check = checkValidate(bi * 3, bj * 3)
if (!check) return false
if (bj === 2) {
bi += 1
bj = 0
} else {
bj += 1
}
}
return Object.values(map.column).every(column => new Set(column).size === column.length)
}
// Test case
console.log(
// false
isValidSudoku(
[
[".",".","4",".",".",".","6","3","."],
[".",".",".",".",".",".",".",".","."],
["5",".",".",".",".",".",".","9","."],
[".",".",".","5","6",".",".",".","."],
["4",".","3",".",".",".",".",".","1"],
[".",".",".","7",".",".",".",".","."],
[".",".",".","5",".",".",".",".","."],
[".",".",".",".",".",".",".",".","."],
[".",".",".",".",".",".",".",".","."]
]
)
)