• Leetcode-36. 有效的数独


    36. 有效的数独

    判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

    1. 数字 1-9 在每一行只能出现一次。
    2. 数字 1-9 在每一列只能出现一次。
    3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

    数独部分空格内已填入了数字,空白格用 '.' 表示。

    简单的想法就是按行,列,块三次遍历数组,确保有效。进一步可以一次迭代就可以,每次迭代时记录下行,列,块的已经看到的元素,(可以使用set记录)。然后遍历的时候如果看到之前的记录中有当前的数,就无效。需要注意的时,假设顺序为从左到右,从上到下,那么

    • i行第j列的数就位于第(i/3)*3+j/3块,
    • i块第j个数的行和列就分别为((i/3)*3+j/3, (i%3)*3+j%3)
    class Solution {
    public:
        bool isValidSudoku(vector<vector<char>>& board) {
            vector<set<char>> row(9);
            vector<set<char>> col(9);
            // 方块
            for (int i = 0; i < 9; ++i) {
                set<char> num;
                for (int j = 0; j < 9; ++j) {
                    if (board[x][y] != '.') {
                        // i是第几个块,j是块内第几个数, x是第几行,y是第几列
                        int x = (i / 3) * 3 + j / 3;
                        int y = (i % 3) * 3 + j % 3;
                        if (row[x].find(board[x][y]) == row[x].end()) {
                            row[x].insert(board[x][y]);
                        } else {
                            return false;
                        }
                        if (col[y].find(board[x][y]) == col[y].end()) {
                            col[y].insert(board[x][y]);
                        } else {
                            return false;
                        }
                        if (num.find(board[x][y]) == num.end()) {
                            num.insert(board[x][y]);
                        } else {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    };
    

    这里面比较大的时间损耗在于set的查找,可以用一个二维数组来代替,比如创建一个二维数组row,第i行,第j列表示数独内第i行存不存在j+1这个数。这样会比较快。

    class Solution {
    public:
        bool isValidSudoku(vector<vector<char>>& board) {
            int row[9][9] = {0};
            int col[9][9] = {0};
            int num[9][9] = {0};
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    // i是第几行,j是第几列
                    if (board[i][j] != '.') {
                        int cur_num = board[i][j] - '1';
                        if (row[i][cur_num]) {
                            return false;
                        }
                        if (col[j][cur_num]) {
                            return false;
                        }
                        int block = (i / 3) * 3 + j / 3;
                        if (num[block][cur_num]) {
                            return false;
                        }
                        row[i][cur_num] = 1;
                        col[j][cur_num] = 1;
                        num[block][cur_num] = 1;
                    }
                }
            }
            return true;
        }
    };
    
    

    但在Leetcode上测试好像也没快多少_

  • 相关阅读:
    MongoDB学习笔记-查询
    【ASP.NET MVC 回顾】HtmlHepler应用-分页组件
    浅谈.NET中闭包
    浅析 public static void main(String[] args)
    关于SQL Server 无法生成 FRunCM 线程(不完全)
    设计模式-02.单例模式
    设计模式-01.工厂模式
    GC垃圾回收机制
    Spring自学笔记
    关于面试
  • 原文地址:https://www.cnblogs.com/eggplant-is-me/p/13985358.html
Copyright © 2020-2023  润新知