LeetCode:Valid Sudoku与Sudoku Solver

Valid Sudoku


1、题目:
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character ‘.’.
这里写图片描述
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.


2、代码:
起初,天真的我以为有效与否,看他能不能解出来,结果老是超时,后来还百度一下,难道有更精妙的解法。看了几个帖子后发现都是递归啊!!!后来扫了一下别人的代码发现别人的怎么这么简单,慢着,竟然没有递归!!!结果再看题目,特别是把note翻译了一下,有效的不一定有解,一万个奔腾那个。于是就三个类别判断了一下,竟然是这样!!!

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        bool bflag[10];

        for(int j=0;j<9;++j)//水平,横向
        {
            for(int i=1;i<10;++i)
            {
                bflag[i]=false;
            }
            for(int i=0;i<9;++i)
            {
                if(board[j][i]!='.'&&bflag[board[j][i]-48])
                {
                    return false;
                }
                else if(board[j][i]!='.')
                {
                    bflag[board[j][i]-48]=true;
                }
            }
        }

        for(int j=0;j<9;++j)//竖直
        {
            for(int i=1;i<10;++i)
            {
                bflag[i]=false;
            }
            for(int i=0;i<9;++i)
            {
                if(board[i][j]!='.'&&bflag[board[i][j]-48])
                {
                    return false;
                }
                else if(board[i][j]!='.')
                {
                    bflag[board[i][j]-48]=true;
                }
            }
        }

        for(int fy=0;fy<3;++fy)
        {
            for(int fx=0;fx<3;++fx)
            {
                 for(int i=1;i<10;++i)
                {
                    bflag[i]=false;
                }
                for(int j=fy*3;j<(fy+1)*3;++j)
                {
                    for(int i=fx*3;i<(fx+1)*3;++i)
                    {
                       if(board[j][i]!='.'&&bflag[board[j][i]-48])
                        {
                            return false;
                        }
                        else if(board[j][i]!='.')
                        {
                            bflag[board[j][i]-48]=true;
                        } 
                    }
                }
            }
        }
        return true;
    }
};

当然了,这个也有要注意的地方,一行判断完再判断下一行时候要对数组全部置false,列和子格也是的,否则,又是许久肉眼找bug。


Sudoku Solver


1、题目:
Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character ‘.’.

You may assume that there will be only one unique solution.
这里写图片描述
这里写图片描述


2、代码:
在上个题目的折腾中,我的这个题目基本完工,所以很快就开始测试了。

class Solution {
public:
    bool isFill(vector<vector<char>>& board)//满员判断
    {
        for(int j=0;j<9;++j)
        {
            for(int i=0;i<9;++i)
            {
                if(board[j][i]=='.')
                {
                    return false;
                }
            }
        }
        return true;
    }
    void solveSudoku(vector<vector<char>>& board) {
        bool flag[10];
        for(int i=1;i<10;++i)
        {
            flag[i]=false;
        }
        int i=0,j=0;
        for(j=0;j<9;++j)
        {
            for(i=0;i<9&&board[j][i]!='.';++i);
            if(i<9) break;
        }
        if(j==9&&i==9)    //fill exit  
        {
            return;
        }
        for(int t=0;t<9;++t)//水平,横向
        {
            if(board[j][t]!='.'&&(!flag[board[j][t]-48]))
            {
                flag[board[j][t]-48]=true;
            }
        }
        for(int t=0;t<9;++t)//竖直
        {
            if(board[t][i]!='.'&&(!flag[board[t][i]-48]))
            {
                flag[board[t][i]-48]=true;
            }
        }
        int fx=(i/3)*3,fy=(j/3)*3;
        for(int t=fy;t<fy+3;++t)
        {
            for(int k=fx;k<fx+3;++k)
            {
                if(board[t][k]!='.'&&(!flag[board[t][k]-48]))
                {
                    flag[board[t][k]-48]=true;
                }
            }
        }
        int t=0;
        while(!isFill(board))
        {
            ++t;
            for(;t<10&&flag[t];++t);
            if(t==10)   
            {
                board[j][i]='.';
                return;
            }
            board[j][i]=t+48;
            solveSudoku(board);

        }
    }
};

3、总结:
A、退出递归的条件,已经填满或是当前位置没有可填数字。
B、哈希表要flag[10],数字是1–9。
C、满员判断函数,确定是否填满,决定结束与否。
D、如果此数填入,在后面发现无法填满时候,要将此数及后面的数还原成没有数的状态,如

             if(t==10)   
            {
                board[j][i]='.';
                return;
            }

E、哈希表一个就够了,在三类情况都对他进行查询和赋值。
F、int fx=(i/3)*3,fy=(j/3)*3;这个似乎要记一下,i/3表示横向第几个子格,是整数,再乘3定位。


实际执行

代码就不贴了,把上面的改一下就可以了。
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值