LeetCode——37. 解数独

Posted 何许

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode——37. 解数独相关的知识,希望对你有一定的参考价值。

 

 

  采用递归的思想,穷举不在同一行,同一列,同一小方块出现的数字,考虑查找效率,采用set保存。

  

set<char> set_m[9];
set<char> set_row[9];
set<char> set_col[9];

bool notContain(char group[9] , char x)
{
    for (int i = 0; i < 9;i++)
    if (group[i] == x)
        return true;

    return false;
}
void insert(vector<vector<char>>& board, int x,int y,char value)
{
    set_col[x].insert (value);
    set_row[y].insert( value );
    set_m[(y / 3 + x / 3 * 3)].insert(value);
}
void erase(vector<vector<char>>& board, int x, int y, char value)
{
    set_col[x].erase(value);
    set_row[y].erase(value);
    set_m[(y / 3 + x / 3 * 3)].erase(value);
}

void cal(vector<vector<char>>& board,vector<vector<char>>& result,int x, int y){
    if (x > 8 || y > 8)
        return;
//    cout << "cal : " << x << " _ " << y << "       ";
    if (x == 8 && y == 8)
    {
        //cout << endl;
        for (int x = 0; x < 9; x++)
        {
            for (int y = 0; y < 9; y++)
            {
                //cout << board[x][y];
                result[x][y] = board[x][y];
            }
        //    cout << endl;
        }
        return;
    }
    if (y == 8)
    {
        y = 0;
        x++;
    }
    else
        y++;

    //如果已经排序,则跳到下一个递归
    if (board[x][y] != \'.\')
    {
        cal(board,result, x, y);
        return;
    }
    //处理未排序的位置
    for (char i = \'1\'; i <= \'9\'; i++)
    {
        if (set_row[y].find(i) == set_row[y].end() && 
            set_col[x].find(i) == set_col[x].end() &&
            set_m[(y / 3 + x / 3 * 3)].find(i) == set_m[(y / 3 + x / 3 * 3)].end())
        {
            board[x][y] = i;
            insert(board, x,y,i);
            cal(board,result,  x, y);
            board[x][y] = \'.\';
            erase(board, x, y, i);
        }

    }

}

class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
    if (board.size() != 9)
    {
        cout << "input data Error " << endl;
        return;
    }
    for (auto row : board)
    {
        if (row.size() != 9)
        {
            cout << "input data Error " << endl;
            return;
        }
    }
    vector<vector<char>> result(9, vector<char>(9, \'.\'));
    for(int i=0;i<9;i++)
    {
      set_m[i].clear();
      set_row[i].clear();
      set_col[i].clear();
    }

    for (int x = 0; x < 9; x++)
    {
        for (int y = 0; y < 9; y++)
        {
            if (board[x][y] != \'.\')
            {
                set_col[x].insert( board[x][y]);
                set_row[y].insert( board[x][y]);
                set_m[(y / 3 + x / 3 * 3)].insert(board[x][y]);
            }
        }
    }
    cal(board, result,0, -1);
            for (int x = 0; x < 9; x++)
        {
            for (int y = 0; y < 9; y++)
            {
                //cout << board[x][y];
                board[x][y] =result[x][y];
            }
        //    cout << endl;
        }
}
};

 

代码如上,效率较低。主要是存在过多的遍历赋值,可以简化

 

以上是关于LeetCode——37. 解数独的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-37.解数独

算法leetcode|37. 解数独(rust重拳出击)

LeetCode 37. Sudoku Solver —— 解数独

leetcode 37解数独

leetcode题解之37. 解数独

Python描述 LeetCode 37. 解数独