zoukankan      html  css  js  c++  java
  • leetcode第36题--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.

    这题相对上题值判断是否合法来说就是更难了。

    网上有很多解法,有的复杂有的简洁。我把我理解的记录如下:

    思路应该要很明确。利用回溯法。这里是用递归的回溯。我特意复习了下回溯法。就是利用dfs。一直遍历找到符合的解,这个过程有相应的剪枝,剪就通过下面的isValid来进行。需要注意的地方已经给了注释。诉说千字不如代码一行。

    class Solution {
        private:
        bool isValid(vector<vector<char> > &board, int x, int y)
        {
            for (int i = 0; i < 9; ++i) // 判断行是否有重复字符
            {
                if (board[i][y] == board[x][y] && i != x)
                    return false;
            }
            for (int i = 0; i < 9; ++i) //
            {
                if (board[x][i] == board[x][y] && i != y)
                    return false;
            }
            for (int i = 3*(x/3); i < 3*(x/3)+3; ++i) // 子九宫是否有重复
                for (int j = 3*(y/3); j < 3*(y/3)+3; ++j) // 纸上画一个框就能推出其中每个格子的起点和终点与xy的关系
                {
                    if (board[i][j] == board[x][y] && i != x && j != y)
                        return false;
                }
            return true; // 都没有就返回合法
        }
    public:
        bool solveSudoku(vector<vector<char> > &board)
        {
            // backtracking
            for (int i = 0; i < 9; ++i)
                for (int j = 0; j < 9; ++j)
                {
                    if ('.' == board[i][j])
                    {
                        for (int k = 1; k <= 9; ++k) // 注意了是1到9,别误以为0到8
                        {
                            board[i][j] = '0'+ k; // = 别写成 == 了,调式了十分钟发现我写成==,泪崩
                            if (isValid(board, i, j) && solveSudoku(board)) // 如果加入的数合法,并且,加入后的有解,那就true
                                return true;
                            board[i][j] = '.'; // if没有返回那就是k取值不合法,所以要重新把元素恢复为'.'
                        }
                        return false;
                    }
                }
            return true; // 最后一次所有的都填了数字了,解成功了就返回正确
        }
    };
  • 相关阅读:
    第九篇:网络编程
    第十篇:并发编程
    Python-GIL 进程池 线程池
    Python-生产者消费模型 线程
    Python-互斥锁 进程间通讯
    第八篇:异常处理
    第六篇:面向对象
    第四篇:模块与包
    【转】英语中的并列连词,只知道 and 和 but?11组并列连词,一篇搞定!
    【转】英语中的从属连词,28个,一篇搞定(句子结构2)
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4049561.html
Copyright © 2011-2022 走看看