Solution 1Three Passes
- TimeO(1)
- SpaceO(1)
Strictly O(1): the board is fixed at 9x9, so the work is pinned at 243 cell visits
(81 x 3 passes) and no set ever exceeds 9 entries. That label fits any correct solution though, brute force included, so the useful form is the generalised one: on an n x n board this is O(n^2) time, which is linear in the input (the input IS n^2 cells) and therefore optimal, with O(n) space.
Three passes costs 3x the cell reads of the single-pass [hash-set] version below, but holds one set alive at a time instead of 3n of them, O(n) space against O(n^2).
At 9x9 both collapse to O(1), but the trade is real on a generalised board.
Pitfalls
'.' is added to dup unconditionally, so the sets fill with dots. That is harmless only because board[r][c] != '.' is evaluated first and short-circuits before the membership test can ever fire on a dot. A continue on '.' would say it directly
Solved in 14m
class Solution:
'''
Time Complexity: O(1)
Space Complexity: O(1)
Pitfalls: '.' is added to `dup` unconditionally, so the sets fill with dots. That is harmless only because `board[r][c] != '.'` is evaluated first and short-circuits before the membership test can ever fire on a dot. A `continue` on '.' would say it directly.
Strictly O(1): the board is fixed at 9x9, so the work is pinned at 243 cell visits
(81 x 3 passes) and no set ever exceeds 9 entries. That label fits any correct
solution though, brute force included, so the useful form is the generalised one:
on an n x n board this is O(n^2) time, which is linear in the input (the input IS
n^2 cells) and therefore optimal, with O(n) space.
Three passes costs 3x the cell reads of the single-pass [hash-set] version below,
but holds one set alive at a time instead of 3n of them, O(n) space against O(n^2).
At 9x9 both collapse to O(1), but the trade is real on a generalised board.
'''
def isValidSudoku(self, board: List[List[str]]) -> bool:
for r in range(9):
dup = set()
for c in range(9):
if board[r][c] != '.' and board[r][c] in dup:
return False
dup.add(board[r][c])
for c in range(9):
dup = set()
for r in range(9):
if board[r][c] != '.' and board[r][c] in dup:
return False
dup.add(board[r][c])
for ra in [0, 3, 6]:
for ca in [0, 3, 6]:
dup = set()
for r in range(ra, ra+3):
for c in range(ca, ca+3):
if board[r][c] != '.' and board[r][c] in dup:
return False
dup.add(board[r][c])
return Truepublic boolean isValidSudoku(char[][] board) {
for (int i = 0; i < 9; i++) {
int[] rowDuplicates = new int[10];
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
if (rowDuplicates[board[i][j] - '0'] > 0) {
return false;
}
rowDuplicates[board[i][j] - '0']++;
}
}
}
for (int i = 0; i < 9; i++) {
int[] colDuplicates = new int[10];
for (int j = 0; j < 9; j++) {
if (board[j][i] != '.') {
if (colDuplicates[board[j][i] - '0'] > 0) {
return false;
}
colDuplicates[board[j][i] - '0']++;
}
}
}
for (int i = 0; i < 9; i+=3) {
for (int j = 0; j < 9; j+=3) {
int[] boxDuplicates = new int[10];
for (int r = i; r < i + 3; r++) {
for (int c = j; c < j + 3; c++) {
if (board[r][c] != '.') {
if (boxDuplicates[board[r][c] - '0'] > 0) {
return false;
}
boxDuplicates[board[r][c] - '0']++;
}
}
}
}
}
return true;
}Solution 2Hash Set
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
boxes = [[set() for _ in range(3)] for _ in range(3)]
col = [set() for _ in range(9)]
for i in range(9):
row = set()
for j in range(9):
num = board[i][j]
if num == ".": continue
if num in row or num in col[j] or num in boxes[i//3][j//3]: return False
row.add(num)
col[j].add(num)
boxes[i//3][j//3].add(num)
return Truepublic boolean isValidSudoku2(char[][] board) {
for (int i=0; i<9; i++) {
Set<Character> row = new HashSet<>();
Set<Character> col = new HashSet<>();
Set<Character> box = new HashSet<>();
for (int j=0; j<9; j++) {
if (board[i][j] != '.' && !row.add(board[i][j])) {
return false;
}
if (board[j][i] != '.' && !col.add(board[j][i])) {
return false;
}
if (board[3*(i/3) + j/3][3*(i%3) + j%3] != '.' && !box.add(board[3*(i/3) + j/3][3*(i%3) + j%3])) {
return false;
}
}
}
return true;
}Solution 3Count Array
public boolean isValidSudoku3(char[][] board) {
for (int i=0; i<9; i++) {
int[] row = new int[9];
int[] col = new int[9];
int[] box = new int[9];
for (int j=0; j<9; j++) {
if (board[i][j] != '.') {
if(row[board[i][j] - '1'] > 0) {
return false;
}
row[board[i][j] - '1']++;
}
if (board[j][i] != '.') {
if(col[board[j][i] - '1'] > 0) {
return false;
}
col[board[j][i] - '1']++;
}
int r = 3*(i/3) + j/3;
int c = 3*(i%3) + j%3;
if (board[r][c] != '.') {
if (box[board[r][c] - '1'] > 0) {
return false;
}
box[board[r][c] - '1']++;
}
}
}
return true;
}