leetcode
Medium
36. Valid Sudoku

36. Valid Sudoku

LeetCode Link (opens in a new tab)

array hash table

Description

Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:

Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition. Note:

A Sudoku board (partially filled) could be valid but is not necessarily solvable. Only the filled cells need to be validated according to the mentioned rules.

Example cases

Example 1:

  • Input: 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"]]
  • Output: true

Example 2:

  • Input: board =
[["8","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"]]
  • Output: false
  • Explanation: Same as Example 1, except with the 5 in the top left corner being modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.

Constraints

  • board.length == 9
  • board[i].length == 9
  • board[i][j] is a digit 1-9 or '.'.

Approach

주어진 9 x 9 스도쿠 판이 valid한지 확인하는 문제이다. 스도쿠게임은

  • row에 1~9까지의 숫자가 중복되지 않아야하고,
  • column에 1~9까지의 숫자가 중복되지 않아야하며,
  • 3x3 sub-box에 1~9까지의 숫자가 중복되지 않아야한다.

brute-force로 배열의 모든 숫자를 순회하며 위 조건을 충족하는지 확인하면 되지만, 이는 O(n3)O(n^3)의 시간복잡도를 가지기 때문에 hash table로 좀 더 효율적으로 문제를 풀 수 있다.
row, column, sub-box 3개의 Map 배열을 만들어 이미 Map에 숫자가 존재하면 바로 false를 반환하고, 존재하지 않으면 Map에 숫자를 추가한다.
스도쿠 판을 한번 순회하는걸로 문제를 해결할 수 있다.

Solution Code

var isValidSudoku = function(board) {
  let rows = Array.from({ length: 9 }, () => new Map())
  let cols = Array.from({ length: 9 }, () => new Map())
  let subboxes = Array.from({ length: 9 }, () => new Map())
 
  for (let i = 0; i < board.length; i += 1) {
    for (let j = 0; j < board[i].length; j += 1) {
      if (board[i][j] === '.') {
        continue;
      }
 
      if (rows[i].has(board[i][j])) {
        return false
      } else {
        rows[i].set(board[i][j], true)
      }
 
      if (cols[j].has(board[i][j])) {
        return false
      } else {
        cols[j].set(board[i][j], true)
      }
 
      let subboxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3);
      if (subboxes[subboxIndex].has(board[i][j])) {
        return false
      } else {
        subboxes[subboxIndex].set(board[i][j], true)
      }
    }
  }
 
  return true
};

Complexity

  • time complexity : O(n2)O(n^2)
  • space complexity : O(n)O(n)