37 - Sudoku Solver

Problem

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 the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.


A sudoku puzzle...


...and its solution numbers marked in red.

Note:

  • The given board contain only digits 1-9 and the character '.'.
  • You may assume that the given Sudoku puzzle will have a single unique solution.
  • The given board size is always 9x9.

Code

public class Solution {
    
    private final static List<Character> chars = Arrays.asList('1', '2', '3', '4', '5', '6', '7', '8', '9');

    private List<Node> nodes;

    private char[][] board;

    private boolean rows[][];

    private boolean cols[][];

    private boolean square[][];

    public void solveSudoku(char[][] board) {
        this.board = board;
        this.rows = new boolean[9][10];
        this.cols = new boolean[9][10];
        this.square = new boolean[9][10];
        this.nodes = new LinkedList<Node>();
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (this.board[i][j] != '.') {
                    int val = this.board[i][j] - '0';
                    this.rows[i][val] = true;
                    this.cols[j][val] = true;
                    this.square[i / 3 * 3 + j / 3][val] = true;
                }
            }
        }
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    Set<Character> set = new HashSet<Character>(chars);
                    Node node = new Node(j, i, i / 3 * 3 + j / 3, set);
                    this.removeNotImpossible(node);
                    this.nodes.add(node);
                }
            }
        }
        Collections.sort(this.nodes, new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                return o1.getSet().size() - o2.getSet().size();
            }
        });
        this.dfs(this.nodes);
    }

    private boolean dfs(List<Node> nodes) {
        if (nodes.isEmpty()) {
            return true;
        }
        Node cur = nodes.remove(0);
        for (char ch : cur.getSet()) {
            int val = ch - '0';
            if (this.check(cur.getX(), cur.getY(), cur.getIndex(), val)) {
                this.board[cur.getY()][cur.getX()] = ch;
                this.rows[cur.getY()][val] = true;
                this.cols[cur.getX()][val] = true;
                this.square[cur.getIndex()][val] = true;
                if (this.dfs(nodes)) {
                    return true;
                }
                this.board[cur.getY()][cur.getX()] = '.';
                this.rows[cur.getY()][val] = false;
                this.cols[cur.getX()][val] = false;
                this.square[cur.getIndex()][val] = false;
            }
        }
        nodes.add(0, cur);
        return false;
    }

    private void removeNotImpossible(Node node) {
        for (int i = 1; i < 10; ++i) {
            if (!this.check(node.getX(), node.getY(), node.getIndex(), i)) {
                node.getSet().remove((char)('0' + i));
            }
        }

    }

    private boolean check(int x, int y, int index, int val) {
        return !this.rows[y][val] && !this.cols[x][val] && !this.square[index][val];
    }

    private class Node {

        private int x;

        private int y;

        private int index;

        private Set<Character> set;

        public Node(int x, int y, int index, Set<Character> set) {
            this.x = x;
            this.y = y;
            this.index = index;
            this.set = set;
        }

        public int getX() {
            return this.x;
        }

        public int getY() {
            return this.y;
        }

        public int getIndex() {
            return this.index;
        }

        public Set<Character> getSet() {
            return this.set;
        }

    }
    
}

Link: https://leetcode.com/problems/sudoku-solver/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值