All Downloads are FREE. Search and download functionalities are using the official Maven repository.

g0001_0100.s0037_sudoku_solver.Solution Maven / Gradle / Ivy

There is a newer version: 1.38
Show newest version
package g0001_0100.s0037_sudoku_solver;

// #Hard #Array #Matrix #Backtracking #2023_08_09_Time_2_ms_(99.55%)_Space_40.4_MB_(20.80%)

import java.util.ArrayList;
import java.util.List;

/**
 * 37 - Sudoku Solver\.
 *
 * Hard
 *
 * Write a program to solve a Sudoku puzzle by filling the empty cells.
 *
 * A sudoku solution must satisfy **all of the following rules**:
 *
 * 1.  Each of the digits `1-9` must occur exactly once in each row.
 * 2.  Each of the digits `1-9` must occur exactly once in each column.
 * 3.  Each of the digits `1-9` must occur exactly once in each of the 9 `3x3` sub-boxes of the grid.
 *
 * The `'.'` character indicates empty cells.
 *
 * **Example 1:**
 *
 * ![](https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Sudoku-by-L2G-20050714.svg/250px-Sudoku-by-L2G-20050714.svg.png)
 *
 * **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:**
 *
 *     [["5","3","4","6","7","8","9","1","2"],
 *     ["6","7","2","1","9","5","3","4","8"],
 *     ["1","9","8","3","4","2","5","6","7"],
 *     ["8","5","9","7","6","1","4","2","3"],
 *     ["4","2","6","8","5","3","7","9","1"],
 *     ["7","1","3","9","2","4","8","5","6"],
 *     ["9","6","1","5","3","7","2","8","4"],
 *     ["2","8","7","4","1","9","6","3","5"],
 *     ["3","4","5","2","8","6","1","7","9"]]
 *
 * **Explanation:** The input board is shown above and the only valid solution is shown below:
 *
 * ![](https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Sudoku-by-L2G-20050714_solution.svg/250px-Sudoku-by-L2G-20050714_solution.svg.png) 
 *
 * **Constraints:**
 *
 * *   `board.length == 9`
 * *   `board[i].length == 9`
 * *   `board[i][j]` is a digit or `'.'`.
 * *   It is **guaranteed** that the input board has only one solution.
**/
public class Solution {
    private List emptyCells = new ArrayList<>();
    private int[] rows = new int[9];
    private int[] cols = new int[9];
    private int[] boxes = new int[9];

    public void solveSudoku(char[][] board) {
        for (int r = 0; r < 9; r++) {
            for (int c = 0; c < 9; c++) {
                if (board[r][c] == '.') {
                    emptyCells.add(new int[] {r, c});
                } else {
                    int val = board[r][c] - '0';
                    int boxPos = r / 3 * 3 + c / 3;
                    rows[r] |= 1 << val;
                    cols[c] |= 1 << val;
                    boxes[boxPos] |= 1 << val;
                }
            }
        }
        backtracking(board, 0);
    }

    private boolean backtracking(char[][] board, int i) {
        // Check if we filled all empty cells?
        if (i == emptyCells.size()) {
            return true;
        }

        int r = emptyCells.get(i)[0];
        int c = emptyCells.get(i)[1];
        int boxPos = (r / 3) * 3 + c / 3;
        for (int val = 1; val <= 9; ++val) {
            // skip if that value is existed!
            if (hasBit(rows[r], val) || hasBit(cols[c], val) || hasBit(boxes[boxPos], val)) {
                continue;
            }
            board[r][c] = (char) ('0' + val);
            // backup old values
            int oldRow = rows[r];
            int oldCol = cols[c];
            int oldBox = boxes[boxPos];
            rows[r] |= 1 << val;
            cols[c] |= 1 << val;
            boxes[boxPos] |= 1 << val;
            if (backtracking(board, i + 1)) {
                return true;
            }
            rows[r] = oldRow;
            cols[c] = oldCol;
            boxes[boxPos] = oldBox;
        }
        return false;
    }

    private boolean hasBit(int x, int k) {
        return (x >> k & 1) == 1;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy