Leetcode---Sudoku Solver

来源:互联网 发布:c语言中调用函数 编辑:程序博客网 时间:2024/06/02 00:58

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.


Have you been asked this question in an interview?

首先leetcode只要求9*9的输入,所以不可能出现时间和空间不够用的问题。
基本思路是回溯,回溯类似就是DFS,不同的是某层失败后要回到上一层,失败的一层要恢复原样。
另外,回溯也要使用递归,递归需要有收敛条件,就是要有一段code,不会调用自身而返回。

这里的关键点是对于一旦出现解出现的情况,要防止递归函数返回后修改数据,所以要标记解出现的情况,可以用返回值或全局变量标记:

全局变量:

bool flag= false;bool check(int k, vector<vector<char> > &board){        int x=k/9;        int y=k%9;        for (int i = 0; i < 9; i++)            if (i != x && board[i][y] == board[x][y])                return false;        for (int j = 0; j < 9; j++)            if (j != y && board[x][j] == board[x][y])                return false;        for (int i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)            for (int j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)                if (i != x && j != y && board[i][j] == board[x][y])                    return false;        return true;    }void dfs(int num,vector<vector<char> > &board){    if(num==81){        flag=true;        return;    }    else{        int x=num/9;        int y=num%9;        if(board[x][y]=='.'){            for(int i=1;i<=9;i++){                board[x][y]=i+'0';                if(check(num,board)){                    dfs(num+1,board);                    if(flag)                        return;                }            }            board[x][y]='.';        }        else{            dfs(num+1,board);        }    }}void solveSudoku(vector<vector<char> > &board) {    dfs(0,board);}

返回值:

    int n,m;    bool check(int k, vector<vector<char> > &board){        int x=k/n;        int y=k%m;        for (int i = 0; i < n; i++)            if (i != x && board[i][y] == board[x][y])                return false;        for (int j = 0; j < m; j++)            if (j != y && board[x][j] == board[x][y])                return false;        for (int i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)            for (int j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)                if (i != x && j != y && board[i][j] == board[x][y])                    return false;        return true;    }    bool f(int i, vector<vector<char> > &board){        if(i==n*m)            return true;        if(board[i/n][i%m]=='.'){            for(int k=1;k<=9;k++){                board[i/n][i%m]=k+'0';                    if(check(i,board) && f(i+1,board))                            return true;            }            board[i/n][i%m]='.';            return false;        }        else            return f(i+1,board);    }    void solveSudoku(vector<vector<char> > &board) {        n=board.size();        m=board[0].size();        f(0,board);    }

上面两个都是得到一个解就返回,还有是可以得到所有解的情况,也就是在解出现的时候存下来。

vector<vector<vector<char> >> sum;bool check(int k, vector<vector<char> > &board){        int x=k/9;        int y=k%9;        for (int i = 0; i < 9; i++)            if (i != x && board[i][y] == board[x][y])                return false;        for (int j = 0; j < 9; j++)            if (j != y && board[x][j] == board[x][y])                return false;        for (int i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)            for (int j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)                if (i != x && j != y && board[i][j] == board[x][y])                    return false;        return true;    }void dfs(int num,vector<vector<char> > &board){    if(num==81){        sum.push_back(board);        return;    }    else{        int x=num/9;        int y=num%9;        if(board[x][y]=='.'){            for(int i=1;i<=9;i++){                board[x][y]=i+'0';                if(check(num,board)){                    dfs(num+1,board);                    //if(flag)                      //  return;                }            }            board[x][y]='.';        }        else{            dfs(num+1,board);        }    }}void solveSudoku(vector<vector<char> > &board) {    dfs(0,board);}int main(){    vector<string> myboard({"...748...","7........",".2.1.9...","..7...24.",".64.1.59.",".98...3..","...8.3.2.","........6","...2759.."});    vector<char> temp(9,'.');    vector<vector<char> > board(9,temp);    for(int i=0;i<myboard.size();i++){        for(int j=0;j<myboard[i].length();j++){            board[i][j]=myboard[i][j];        }    }    solveSudoku(board);    for(int k=0;k<sum.size();k++){    for(int i=0;i<sum[k].size();i++){        for(int j=0;j<sum[k][i].size();j++){            cout<<sum[k][i][j]<<" ";        }        cout<<endl;    }    cout<<"######"<<endl;    }    cout<<"sum is "<<sum.size()<<endl;    cout << "Hello world!" << endl;    return 0;}

输出了8个解。




0 0
原创粉丝点击