LeetCode 37. 解數獨

畫船聽雨發表於2018-07-09

題目描述

這裡寫圖片描述

解題思路

暴力遞迴

使用dfs進行暴力遞迴,需要判斷一下三個條件,標記一下是否出現過,行、列以及3*3的小格子中是否出現過。
注意遞迴結束的條件,失敗後不要返回(在這裡寫錯了,沒注意到)。

程式碼實現

int r[12][12];
int c[12][12];
int g[12][12];
int mp[12][12];

class Solution
{
public:

    int Change(int x)
    {
        if(x <= 3) return 1;
        if(x <= 6) return 2;
        return 3;
    }

    int dfs(int x, int y)
    {
        if(x == 10)
            return 1;
        int flag = 0;
        if(mp[x][y] != 0)
        {
            if(y == 9)
                flag =  dfs(x+1, 1);
            else
                flag = dfs(x, y+1);
            return flag;
        }
        else
        {
            int sx = Change(x);
            int sy = Change(y);
            if(sx == 2) sy += 3;
            if(sx == 3) sy += 6;
            flag = 0;
            for(int i = 1; i <= 9; i++)
            {
                if(!r[x][i] && !c[y][i] && !g[sy][i])
                {
                    mp[x][y] = i;
                    r[x][i] = 1;
                    c[y][i] = 1;
                    g[sy][i] = 1;

                    if(y == 9) flag = dfs(x+1, 1);
                    else flag = dfs(x, y+1);
                    if(!flag)
                    {
                        mp[x][y] = 0;
                        r[x][i] = 0;
                        c[y][i] = 0;
                        g[sy][i] = 0;
                    }
                    else
                    return flag;
                }
            }
        }

        return 0;
    }

    void solveSudoku(vector<vector<char>>& board)
    {
        memset(r, 0, sizeof(r));
        memset(c, 0, sizeof(c));
        memset(g, 0, sizeof(g));
        for(int i = 0; i < 9; ++i)
        {
            for(int j = 0; j < 9; ++j)
            {
                if(board[i][j] == '.')
                    mp[i+1][j+1] = 0;
                else
                    mp[i+1][j+1] = board[i][j]-'0';

                if(mp[i+1][j+1] == 0) continue;

                int num = mp[i+1][j+1];

                r[i+1][num] = 1;
                c[j+1][num] = 1;

                int x = Change(i+1);
                int y = Change(j+1);

                if(x == 2) y += 3;
                if(x == 3) y += 6;

                g[y][num] = 1;
            }
        }
        dfs(1,1);

        for(int i = 1; i <= 9; ++i)
        {
            for(int j = 1; j <= 9; ++j)
                board[i-1][j-1] = char(mp[i][j]+'0');
        }
    }
};
//測試樣例
530070000
600195000
098000060
800060003
400803001
700020006
060000280
000419005
000080079

相關文章