14 解数独(leecode 37)

1 问题

编写一个程序,通过填充空格来解决数独问题。

一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
在这里插入图片描述一个数独。
在这里插入图片描述答案被标成红色。

提示:

给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

2 解法

一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性。
在这里插入图片描述

class Solution {
    
    
public:
    bool backtracking(vector<vector<char>>& board)
    {
    
    
        //遍历棋盘行
        for(int i = 0; i < board.size(); i++)
        {
    
    
            //遍历棋盘列
            for(int j = 0; j < board[0].size(); j++)
            {
    
    
                //board[i][j]位置不为空,则开始下次循环
                if(board[i][j] != '.')
                    continue;
                for(char k = '1'; k <= '9'; k++)
                {
    
    
                    //判断在i、j位置是否能够放入k
                    if(isValid(i, j, k, board))
                    {
    
    
                        board[i][j] = k;
                        //递归
                        if(backtracking(board)) // 如果找到合适一组立刻返回
                            return true;
                        //回溯
                        board[i][j] = '.';
                    }   
                }
                //1~9都不能放入board[i][j]位置
                return false;
            }
        }
        return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
    }
    bool isValid(int row, int col, char k, vector<vector<char>>& board)
    {
    
    
        //1. 1-9每行只能出现一次,遍历0-row-1,看是否出现k
        for(int i = 0; i < 9; i++)
        {
    
    
            if(board[row][i] == k)
                return false;
        }
        //2. 1-9每列只能出现一次,遍历0-col-1,看是否出现k
        for(int i = 0; i < 9; i++)
        {
    
    
            if(board[i][col] == k)
                return false;
        }
        //3. 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次
        //找到 3x3 宫格的左上角顶点位置
        int startX = (row / 3) * 3;
        int startY = (col / 3) * 3;
        for(int i = startX; i < startX + 3; i++)
        {
    
    
            for(int j = startY; j < startY + 3; j++)
            {
    
    
                if(board[i][j] == k)
                    return false;
            }
        }
        return true;
    }
    void solveSudoku(vector<vector<char>>& board) {
    
    
        backtracking(board);
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_42454048/article/details/113888456