【Leetcode】37. Sudoku Solver(代码)

248 阅读1分钟

题目地址:

leetcode.com/problems/su…

解数独。DFS回溯+剪枝。代码如下:

public class Solution {    
    public void solveSudoku(char[][] board) {
        dfs(board, 0);
    }
    
    // 表示正在尝试pos这个位置能填什么数
    private boolean dfs(char[][] board, int pos) {
    	// 略过'.'
        while (pos < 81 && board[pos / 9][pos % 9] != '.') {
            pos++;
        }
        
        // 如果pos == 81,说明已经安全到达了数独最后一个数字之后,也就是已经找到了一个解,返回true
        if (pos == 81) {
            return true;
        }
        
        // 枚举当前位置的数字
        for (int i = 1; i <= 9; i++) {
        	// 开始做尝试
            board[pos / 9][pos % 9] = (char) ('0' + i);
            // 如果满足条件,就枚举下一个数字,如果找到解了,返回true,不再枚举
            if (check(board, pos) && dfs(board, pos + 1) {
            	return true;
            }
            
            // 如果没找到,当前位置要恢复原状,继续找解
            board[pos / 9][pos % 9] = '.';
        }

		// 没找到,返回false
		return false;
    }
    
    private boolean check(char[][] board, int pos) {
        int row = pos / 9, col = pos % 9;
    
        for (int i = 0; i < 9; i++) {
            if (board[row][i] == board[row][col] && i != col) {
                return false;
            }
            if (board[i][col] == board[row][col] && i != row) {
                return false;
            }
        }
        
        int i = row / 3 * 3, j = col / 3 * 3;
        for (int k = 0; k < 3; k++) {
            for (int l = 0; l < 3; l++) {
                if (board[i + k][j + l] == board[row][col] && i + k != row && j + l != col) {
                    return false;
                }
            }
            
        }
        
        return true;
    }
}