import java.util.HashMap; import java.util.Map; /** * Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. * * The Sudoku board could be partially filled, where empty cells are filled * with the character '.'. * * Note: * A valid Sudoku board (partially filled) is not necessarily solvable. Only * the filled cells need to be validated. * * Tags: Hash table */ class ValidSudoku { public static void main(String[] args) { ValidSudoku v = new ValidSudoku(); char[][] board = new char[9][9]; for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { if (i == 0 && j == 0) { board[i][j] = '.'; } else if (i == 0 && j != 0) { board[i][j] = (char)('0' + j + 1); } else { board[i][j] = '.'; } } } v.printBoard(board); System.out.println(v.isValidSudoku(board)); } public boolean isValidSudoku(char[][] board) { boolean[][] row = new boolean[9][9]; boolean[][] col = new boolean[9][9]; boolean[][] box = new boolean[9][9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] != '.') { int num = board[i][j] - '0' - 1; int k = i / 3 * 3 + j / 3; if (row[i][num] || col[j][num] || box[k][num]) { return false; } row[i][num] = col[j][num] = box[k][num] = true; } } } return true; } /** * Use three arrays of integers to do masking */ public boolean isValidSudoku2(char[][] board) { int[] row = new int[9]; int[] col = new int[9]; int[] sqr = new int[9]; for (int i = 0; i < 9; i++){ for (int j = 0; j < 9; j++) { if (board[i][j] != '.') { int num = board[i][j] - '0'; if ((row[i] & 1 << num) > 0) return false; // already in row else row[i] |= 1 << num; if ((col[j] & 1 << num) > 0) return false;// already in col else col[j] |= 1 << num; int sqrIdx = (i - i % 3) + j / 3; // note the square idx if ((sqr[sqrIdx] & 1 << num) > 0) return false; // already else sqr[sqrIdx] |= 1 << num; } } } return true; } /** * hashtable, index as key, mask as value */ public boolean isValidSudoku3(char[][] board) { Map<Integer, Integer> row = new HashMap<Integer, Integer>(); Map<Integer, Integer> col = new HashMap<Integer, Integer>(); Map<Integer, Integer> sqr = new HashMap<Integer, Integer>(); for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { if (board[i][j] != '.') { int num = board[i][j] - '0'; int rowMask = row.containsKey(i) ? row.get(i) : 0; if ((rowMask & 1 << num) > 0) { return false; } else { row.put(i, rowMask | 1 << num); } int colMask = col.containsKey(j) ? col.get(j) : 0; if ((colMask & 1 << num) > 0) { return false; } else { col.put(j, colMask | 1 << num); } int sqrIdx = (i - i % 3) + j / 3; int sqrMask = sqr.containsKey(sqrIdx) ? sqr.get(sqrIdx) : 0; if ((sqrMask & 1 << num) > 0) { return false; } else { sqr.put(sqrIdx, sqrMask | 1 << num); } } } } return true; } private void printBoard(char[][] board) { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { System.out.print(board[i][j] + " "); } System.out.println(); } System.out.println("-----------------"); } }