LeetCode 37. 解数独

题目描述

这里写图片描述

解题思路

暴力递归

使用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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值