LEETCODE: Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.

这个问题初看复杂,时候考虑过递归呢?我们可以把这个问题看做是一个深度优先的遍历过程。如果某个位置有几种可能性,对于每一种可能性递归调用,直到找到可行的解法。


class Solution {
public:
    struct Node {
        int x, y;
        Node(int _x, int _y) : x(_x), y(_y) {
        }
    };

    int sz;
    vector<Node> empties;
    
    bool dfs(vector<vector<char> > &board, int depth) {
        if(depth >= sz) return true;
        
        int ii = empties[depth].x;
        int jj = empties[depth].y;
        
        int flags[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
        
        // Record existing values of the same row
        for(int kk = 0; kk < 9; kk ++) { 
            if(board[ii][kk] != '.') 
                flags[board[ii][kk] - '0'] = 0;
        }
        
        // Record existing values of the same column
        for(int kk = 0; kk < 9; kk ++) {
            if(board[kk][jj] != '.')
                flags[board[kk][jj] - '0'] = 0;
        }
        
        // Record existing values of the same block
        int blocki = (ii / 3) * 3;
        int blockj = (jj / 3) * 3;
        for(int kk = 0; kk < 3; kk ++) {
            for(int mm = 0; mm < 3; mm ++) {
                if(board[blocki + kk][blockj + mm] != '.')
                    flags[board[blocki + kk][blockj + mm] - '0'] = 0;
            }
        }
        
        // For each possible value, try to use depth first recursively searching.
        for(int kk = 1; kk < 10; kk ++) {
            if(flags[kk] == 0) continue;
            
            board[ii][jj] = '0' + kk;
            if(dfs(board, depth + 1))
                return true;
            board[ii][jj] = '.';
        }
        
        return false;
    }
    
    void solveSudoku(vector<vector<char> > &board) {
        // Use empties to store all empty ones.
        for(int ii = 0; ii < 9; ii ++) {
            for(int jj = 0; jj < 9; jj ++) {
                if(board[ii][jj] == '.') {
                    Node node(ii, jj);
                    empties.push_back(node);
                }
            }
        }
        sz = empties.size();
        dfs(board, 0);
    }
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值