leetcode37. 解数独(C++|回溯)

力扣

题目描述

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

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。

leetcode37. 解数独(C++|回溯)_第1张图片

输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:

提示:

board.length == 9
board[i].length == 9
board[i][j] 是一位数字或者 '.'
题目数据 保证 输入数独仅有一个解

leetcode37. 解数独(C++|回溯)_第2张图片

果果念

这道题目感觉挺难的,确实难哈。上一篇做了N皇后问题,也是回溯。回溯是不是都不简单啊,今天只做了两道题目。当然,这道题目也是看了别人的思路之后写出来的,但是没有比着别人抄。我是没有想到题解的话,复杂度也会这么高。这个是很难估量的,但是最大不会超过O(9^(9*9)),啊,算不出来了。我的代码跑了40-80ms,没有别人跑的快。

下面说下我的思路和遇到的坑吧

1.基本思路很好理解,暴力暴力暴力。对一个空闲的位置,要列举1-9,不行的话,再进行回溯,和八皇后问题很像哈。

2.递归一定要及时返回,否则不可收拾。为什么这样说呢?你想,题目中已经说了答案唯一,但是如果不是bool返回的话,那么就有可能找不到正确的值,因为他会一直递归一直递归,太长了。。。这个我之前没有想到,因为之前都是所有的解。就像八皇后问题。

总体说,这道题目是当时大二的时候学长宣传算法协会的时候,为了提高我们的兴趣进行介绍的一个题目,觉得挺有趣的,也一直没有机会去写,也算是画上了一个句号吧。

加油

代码

class Solution {
public:
    void solveSudoku(vector>& board) {
        rowSolve(0,0,board);
    }
    //正在求解第(rowIndex,cloumnIndex)处数字,0~8
    //按照列优先,即先一列一列的来
    bool rowSolve(int rowIndex,int cloumnIndex,vector>& board){
        //找到可行解
        if(rowIndex==9){
            return true;
        }

        //查找下一行
        if(cloumnIndex==9){
            return rowSolve(rowIndex+1,0,board);
        }
        if(board[rowIndex][cloumnIndex]!='.'){
            return rowSolve(rowIndex,cloumnIndex+1,board);
        }else //if(board[rowIndex][cloumnIndex]=='.')
        {
            //满足行,列,九宫格,一次性放1个
            for(int i=1;i<=9;i++){
                if(judge(rowIndex,cloumnIndex,i,board)==true){
                    board[rowIndex][cloumnIndex]='0'+i;
                    if(rowSolve(rowIndex,cloumnIndex+1,board)==true){
                        return true;
                    }
                    board[rowIndex][cloumnIndex]='.';
                }
            }return false;
        }  
    }
    //0 2 0
    bool judge(int r,int c,int num,vector>& board){
        
        //检验第r行
        for(int i=0;i<9;i++){
            if(num==board[r][i]-'0'){
                return false;
            }
        }

        //检验第c列
        for(int i=0;i<9;i++){
            if(num==board[i][c]-'0'){
                return false;
            }
        }

        //九宫格的起点 0 3 6
        int nineR,nineC;
        nineR=(r/3)*3;
        nineC=(c/3)*3;
        cout<

你可能感兴趣的:(算法练习,leetcode,算法,职场和发展)