leecode题目36

自己的解法

我看到这个题目的时候想法就很简单,他三个要求有效:行,列,九宫格

那我就每一个检查一遍不就行了。

这里是我最开始的版本,也花了不少时间,主要代码能力还是欠缺。

class Solution {
    bool isValid(vector<char> &cvec){
        map<char,int> s;
        for(auto c:cvec){
            if(isdigit(c)){
                ++s[c];
                if(s[c]>1){return false;}
            }
        }
        return true;
    }
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        //行
        int h=1;
        for(auto v:board){
            h=h*isValid(v);
            
        }
        //列
        int l=1;
        for(int i=0;i<9;i++){
            vector<char> lv; 
            for(int j=0;j<9;j++){
                lv.push_back(board[j][i]);
            }
            l = l*isValid(lv);
            
        }
        //九宫格
        int n=1;
        for(int i=0;i<9;++i){
            vector<char> nv;
            for(int x=(i%3)*3;x<(i%3)*3+3;x++){
                for(int y=i/3*3;y<i/3*3+3;y++){
                    nv.push_back(board[x][y]);
                } 
            }
            n=n*isValid(nv);
        
        }
        return true;

    }
};

当然这个存在很多问题,不过总算跑通了。

首先我写了一个判断一个vector里面是否是有效的,之后是依靠每一次检查结果累乘,因为又一次无效,结果就会乘上0,最后结果也会是0。

不过这个方法很繁琐,而且也没必要每次都检查,只要检查出错误,直接返回就行了。而且这个累乘的方法,可读性不太行。

后面修改了一下

class Solution {
    bool isValid(vector<char> &cvec){
        map<char,int> s;
        for(auto c:cvec){
            if(isdigit(c)){
                ++s[c];
                if(s[c]>1){return false;}
            }
        }
        return true;
    }
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        //行
        int h=1;
        for(auto v:board){
            if (!isValid(v)) return false;
        }
        //列
        int l=1;
        for(int i=0;i<9;i++){
            vector<char> lv; 
            for(int j=0;j<9;j++){
                lv.push_back(board[j][i]);
            }
            if (!isValid(lv)) return false;
        }
        //九宫格
        int n=1;
        for(int i=0;i<9;++i){
            vector<char> nv;
            for(int x=(i%3)*3;x<(i%3)*3+3;x++){
                for(int y=i/3*3;y<i/3*3+3;y++){
                    nv.push_back(board[x][y]);
                } 
            }
            if (!isValid(nv)) return false;
        }
        return true;

    }
};

这样的改动不仅修正了错误,还提高了代码的效率和可读性。


官方解题

接下来我们看看官方解题

官方的解题是用了一次遍历,这个方法很好,想法是对每一(行,列,九宫格)出现的数进行计数。最后只要有一个计数>1,就说明无效。

使用哈希表记录每一行、每一列和每一个小九宫格中,每个数字出现的次数。只需要遍历数独一次,在遍历的过程中更新哈希表中的计数,并判断是否满足有效的数独的条件即可

这个方法更加简洁高效相比于我的解法。

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int rows[9][9];
        int columns[9][9];
        int subboxes[3][3][9];
        
        memset(rows,0,sizeof(rows));
        memset(columns,0,sizeof(columns));
        memset(subboxes,0,sizeof(subboxes));
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char c = board[i][j];
                if (c != '.') {
                    int index = c - '0' - 1;
                    rows[i][index]++;
                    columns[j][index]++;
                    subboxes[i / 3][j / 3][index]++;
                    if (rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i / 3][j / 3][index] > 1) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/valid-sudoku/solutions/1001859/you-xiao-de-shu-du-by-leetcode-solution-50m6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在C++中,memset 函数是用来将一段内存中的所有字节都设置为特定的值的函数,通常用于初始化数组或结构体。当你写 memset(rows, 0, sizeof(rows)); 目的是将名为 rows 的数组中的所有元素初始化为0。

综上,还需多练。/(ㄒoㄒ)/~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值