zoukankan      html  css  js  c++  java
  • [leetcode] 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.

    思路:

    dfs搜索所有可行解,每个空格从1-9开始逐一遍历,isValid()函数判断该空格是否能放这个数。如果能,则继续dfs递归,如果不能就继续下一个数。如果遍历完了1-9仍然没有可行解,就说明前面的空格填入的数字不对,只能返回改变前面的数字。如此遍历,直到最后一个空格仍然满足条件时,说明找到了可行解。用一个变量flag标记是否找到了可行解。如果没有找到可行解,就还原现在的数字,变成初始状态(.),继续循环;如果找到了,就直接返回而不再循环,逐一退出递归。这个flag很重要,如果没有这个flag,虽然找到了可行解,但是在逐一退出递归的时候余下的循环仍然会继续进行,board[i][j]的值就会改变,这样全部递归推出的时候,结果很奇怪。

    其实晚上还有一种方法,思路差不多,只是将dfs()函数变成又返回值的,而不再是void。这样如果找到可行解,返回true,否则返回false。

    题解:

    class Solution {
    public:
        bool flag = false;            //判断是否找到可行解
        bool isValid(vector<vector<char> > &board, int row, int col) {
            for(int j=0;j<9;j++)
                if(j!=col && board[row][col] == board[row][j])
                    return false;
            for(int i=0;i<9;i++)
                if(i!=row && board[row][col] == board[i][col])
                    return false;
            int x = row/3*3;
            int y = col/3*3;
            for(int i=0;i<3;i++)
                for(int j=0;j<3;j++)
                    if(x+i!=row && y+j!=col && board[row][col] == board[x+i][y+j])
                        return false;
        
            return true;
        }
        void dfs(vector<vector<char> > &board) {
            int k;
            for(int i=0;i<9;i++)
                for(int j=0;j<9;j++) {
                    if(board[i][j]=='.') {
                        for(k=0;k<9;k++) {
                            board[i][j] = k+'1';
                            if(isValid(board,i,j))
                                dfs(board);
                            if(!flag)      //如果没找到可行解,才会还原
                                board[i][j] = '.';
                            else           //已经找打了可行解,直接返回,不在继续接下来的循环
                                return;
                        }
                        if(k==9)           //维护如果填入1—9都不满足时,说明前面的结果有问题
                            return;
                    }
                    if(i==8 && j==8)       //找到了可行解
                        flag = true;
                    }
        }
        
        void solveSudoku(vector<vector<char> > &board) {
            dfs(board);
        }
    };
    View Code

    后话:

    就像在思路中的那样,可以将dfs()函数变成返回值为bool类型的函数,感觉这种方法应该更牛逼一点。就贴出两篇这种方法的吧

    http://www.cnblogs.com/ganganloveu/p/3828401.html 和 http://www.cnblogs.com/panda_lin/archive/2013/11/04/sudoku_solver.html

  • 相关阅读:
    Redis 的 5 个常见使用场景
    当别人给你一个wsdl或者webservice接口时
    Java事务
    Java分布式锁的三种实现方案(redis)
    使用Redis数据库(String类型)
    超详细Redis数据库入门教程
    java对redis的基本操作(初识)
    String、StringBuffer与StringBuilder之间区别
    java正则表达式替换空格和换行符
    Linux 批量管理工具
  • 原文地址:https://www.cnblogs.com/jiasaidongqi/p/4381943.html
Copyright © 2011-2022 走看看