leetcode,解数独算法

本文探讨了在LeetCode中解数独的算法,包括使用位运算的个人解法和一种高效解法。高效解法通过两种思路优化时间复杂度,初期利用已知数推理,后期针对特定情况尝试假设填数。作者分析了样例数据,认为测试用例可能不足以全面评估算法性能。
摘要由CSDN通过智能技术生成

leetcode,解数独算法

这是题目
在这里插入图片描述
这是我的解法,用位运算先把已有的数存入row、col、mat,再用深度优先遍历慢慢推算剩下的,时间复杂度大约O(9^3),主要思想就是依次看每个空格能填什么数。

class Solution {
   
public:
    int row[9]={
   0};
    int col[9]={
   0};
    int mat[9]={
   0};
    bool dfs(vector<vector<char>>& board,int x,int y)
    {
   
        x+=y/9;
        y%=9;
        if(x>=9)
            return true;
        if(board[x][y]!='.')
            return dfs(board,x,y+1);
        for(int i=0;i<9;i++)
        {
   
            int b=3*(x/3)+(y/3);
            int v=1<<i;
            if(row[x]&v||col[y]&v||mat[b]&v)
                continue;
            board[x][y]=('1'+i);
            row[x]|=v;
            col[y]|=v;
            mat[b]|=v;
            if(dfs(board,x,y+1))
                return true;
            board[x][y]='.';
            row[x]-=v;
            col[y]-=v;
            mat[b]-=v;
        }
        return false;
    }
    void solveSudoku(vector<vector<char>>& board)
    {
          
        for(int i=0;i<9;i++)
        {
   
            for(int j=0;j<9;j++)
            {
   
                if(board[i][j]!='.') row[i]|=(1<<(board[i][j]-'1'));
                if(board[j][i]!='.') col[i]|=(1<<(board[j][i]-'1'));
            }
            int x = (i / 3) * 3;
            int y = (i % 3) * 3;
            for (int i0 = x; i0 < x+3; i0++)
            {
    
                for (int j0 = y; j0 < y+3; j0++)               
                    if(board[i0][j0]!='.') mat[i]|=(1<<board[i0][j0]-'1');               
            }
        }
        dfs(board,0,0);
    }
};

这是大佬的解法,在时间复杂度上领先我一大截(用时0ms,我用时8ms),主要思想是
//1、某个格子还有可能填上什么数字
//2、某个数字还有可能填在哪些格子
//前期由于已知数较少,一般用第二种方法推理出必填的数。当推理不出新的必填数时,用第一种方法去尝试假设填数
//以下代码在使用第一种方法尝试假设填数时,使用的对象仅为“能排除7个数,只剩下2个数能填”的格子,并且仅设置了一层假设,居然也过了。看了看测试数据才6个,感觉样例有点少,强度也不好评价

class Solution
{
   
public:

int tryToFill(vector<vector<char>>& board)//这个函数是在推理出了所有必填数而无法再推出更多必填数的时候,开始尝试假设填数而使用的。这个函数内并没有递归,所以假设只有一层。除了在做返回值时的判断,大部分代码和主函数是一样的。以下仅对和主程序不同的部分作注释
{
   
    const int dy[9]={
   0,0,0,1,1,1,2,2,2};
    const int dx[9]={
   0,1,2,0,1,2,0,1,2};

    int numsRemain=81;
    int previousNumsRemain=81;
    int possibleFillPos;
    bool rowFilled[9][9];
    bool columnFilled[9][9];
    bool ninePalaceFilled[9][9];

    for (int i=0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值