LeetCode-Sudoku Solver (递归解法)

题目地址: https://leetcode.com/problems/sudoku-solver/

// 将字符串的数独题转换成 int[9][9]
void setBoard(int board[9][9], char ** b, int boardRowSize, int boardColSize){
    for (int row = 0; row < boardRowSize; ++row)
    for (int col = 0; col < boardColSize; ++col){
        if (b[row][col] == ‘.‘)
            board[row][col] = 0;
        else
            board[row][col] = b[row][col] - ‘0‘;
    }
}
// 计算位置{row,col}的候选个数,并在cands返回候选列表
int calcCandNum(int board[9][9], int row, int col, int * cands){
    if (board[row][col] != 0)
        return 0;// 已知位置
    int cand[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };//
    // 筛除 非法的数字
    // 按行筛除
    for (int i = 0; i < 9; ++i){
        if (board[row][i] != 0)
            cand[board[row][i] - 1] = 0;
    }

    // 按列
    for (int i = 0; i < 9; ++i){
        if (board[i][col] != 0)
            cand[board[i][col] - 1] = 0;
    }

    // 按block
    // 计算左上角坐标
    int r0, c0;
    r0 = (row / 3) * 3;
    c0 = (col / 3) * 3;
    for (int i = r0; i < r0 + 3; ++i)
    for (int j = c0; j < c0 + 3; ++j){
        if (board[i][j] != 0)
            cand[board[i][j] - 1] = 0;
    }
    // 剩下的1 的总和便是 候选个数
    int sum = 0;
    for (int i = 0; i < 9; ++i){
        if (cand[i]){
            cands[sum] = i + 1;
            sum++;
        }
    }
    return sum;
}

typedef struct tagCandidate{
    int row, col;           // 位置
    int n;                  // 候选个数
    int cands[9];           // 候选列表
    int solved;             // 数独是否已经解开
}Candidate;

// 从数独板中返回候选个数最少的位置,其候选信息存入 cand
void getCandidate(int board[9][9], Candidate* cand){
    int candList[9];
    int currN;
    cand->n = 10;
    cand->solved = 1;
    for (int row = 0; row < 9; ++row)
    for (int col = 0; col < 9; ++col){
        if (board[row][col] != 0){ // 该位置有值了
            continue;
        }
        // 说明数独还有空洞
        cand->solved = 0;

        // 计算该孔洞的候选个数,及候选序列
        currN = calcCandNum(board, row, col,candList);
        if (currN < cand->n){
            cand->n = currN;
            cand->row = row;
            cand->col = col;
            for (int i = 0; i < currN; ++i)
                cand->cands[i] = candList[i];
        }
    }
}

int solveBoard(int board[9][9]){
    Candidate cand;
    getCandidate(board, &cand);
    if (cand.solved){
        return 1;
    }
    for (int i = 0; i < cand.n; ++i){
        // guess[cand.row][cand.col] = recursiveFlag;    // flag we guess 好像这个没什么用
        board[cand.row][cand.col] = cand.cands[i];    // fill what we guess
        if (solveBoard(board))
            // we‘d solved it
            return 1;
        else{
            // we‘d not solved it
            // clear what we guess
            // clearGuess(int board[9][9], int guess[])
            board[cand.row][cand.col] = 0;
        }
    }
    // 到这里来!! 不可能 , 无解????
    return 0;
}
// 将结果写回字符数组 b 中
void outputBoard(char **b, int board[9][9]){
    for(int row = 0; row < 9; ++row)
    for(int col = 0; col < 9; ++col){
        b[row][col] = ‘0‘ + (board[row][col]);
    }
}
void solveSudoku(char** b, int boardRowSize, int boardColSize) {
    int board[9][9];
    setBoard(board, b, boardRowSize, boardColSize);
    solveBoard(board);
    outputBoard(b,board);
}
时间: 2024-10-15 12:43:16

LeetCode-Sudoku Solver (递归解法)的相关文章

LeetCode: Sudoku Solver [036]

[题目] 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. [题意] 解

[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. Hide Tags B

[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. 这道求解数独的题是在之

leetcode Sudoku Solver python

# 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 Sol

[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. 方法:解此问题的关键是

LeetCode:Sudoku Solver &amp;&amp; Valid Sudouku

其实数独还是我挺喜欢的一个游戏.原来有本数独的书. 其实Sudoku是基于Valid Sudouku.其实一开始有点想太多.基于平常玩数独的经验,有很多解数独的规则.貌似这个人为判断因素比较多. 而且一开始理解的valid是有解无解,其实这里要求的是给定的board里的数字是否符合规则,不一定能解. 其实我这里有3个函数,一个是判断行除该位置外是否有相同值的,一个是列,最后一个是小正方形里. 而求解使用的是暴力,一个个尝试. public class SudokuSolver {        

【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. 题解:递归.在每个空位

LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)

Valid Sudoku 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 '.'. A partially filled sudoku which is valid. Note: A valid Sudoku boa

[LeetCode][JavaScript]Sudoku Solver

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 re