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;
        }
}
};

 

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

 

posted @ 2018-07-03 22:54  何许  阅读(881)  评论(0编辑  收藏  举报