• 【LeetCode-哈希表】有效的数独


    题目描述

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

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

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

    输入:
    [
      ["5","3",".",".","7",".",".",".","."],
      ["6",".",".","1","9","5",".",".","."],
      [".","9","8",".",".",".",".","6","."],
      ["8",".",".",".","6",".",".",".","3"],
      ["4",".",".","8",".","3",".",".","1"],
      ["7",".",".",".","2",".",".",".","6"],
      [".","6",".",".",".",".","2","8","."],
      [".",".",".","4","1","9",".",".","5"],
      [".",".",".",".","8",".",".","7","9"]
    ]
    输出: true
    

    题目链接: https://leetcode-cn.com/problems/valid-sudoku/

    思路

    最自然的想法就是遍历数组 3 遍,每一遍判断行、列、3x3区域内(下面称为 box)是否有重复的数字。其实,可以在一次遍历中同时判断这 3 种情况。我们使用 3 个哈希表来记录每行、每列、每个 box 中元素的出现的情况。假设当前的位置是 (r, c),则通过行号 r 和列号 c 在对应的哈希表中判断当前元素 board[r][c] 是否出现,对于 box,我们将其编号如下

    这样,box 的编号就等于 (r/3)*3+c/3。所以,我们可以在一次遍历中同时判断行、列、box 中的情况。

    代码如下:

    class Solution {
    public:
        bool isValidSudoku(vector<vector<char>>& board) {
            if(board.empty()) return false;
    
            vector<unordered_set<int>> rows(9);
            vector<unordered_set<int>> cols(9);
            vector<unordered_set<int>> box(9);
    
            for(int i=0; i<9; i++){
                for(int j=0; j<9; j++){
                    if(board[i][j]=='.') continue;
                    int num = board[i][j];
                    if(rows[i].count(num)!=0) return false;
                    if(cols[j].count(num)!=0) return false;
                    if(box[(i/3)*3+j/3].count(num)!=0) return false;
                    rows[i].insert(num);
                    cols[j].insert(num);
                    box[(i/3)*3+j/3].insert(num);
                }
            }
            return true;
        }
    };
    

    上面的代码用的是 unordered_set 来判断一个元素是否存在,也可以直接用数组。代码如下:

    class Solution {
    public:
        bool isValidSudoku(vector<vector<char>>& board) {
            if(board.empty()) return false;
    
            vector<vector<bool>> rows(9, vector<bool>(9, false));
            vector<vector<bool>> cols(9, vector<bool>(9, false));
            vector<vector<bool>> box(9, vector<bool>(9, false));
    
            for(int i=0; i<9; i++){
                for(int j=0; j<9; j++){
                    if(board[i][j]=='.') continue;
                    int val = board[i][j]-'1';
                    if(!rows[i][val] && !cols[j][val] && !box[(i/3)*3+j/3][val]){
                        rows[i][val] = true;
                        cols[j][val] = true;
                        box[(i/3)*3+j/3][val] = true;
                    }else return false;
                }
            }
            return true;
        }
    };
    
    • 时间复杂度:O(1)
    • 空间复杂度:O(1)

    参考

    https://leetcode-cn.com/problems/valid-sudoku/solution/you-xiao-de-shu-du-by-leetcode/

  • 相关阅读:
    Ubuntu格式化分区时的一个小错误
    VS 2013中的新特性browser link
    回车登录,兼容
    ASP.NET MVC 站点设置.html 为起始页
    WebBrowser 禁用右键
    C# 获取时间差(几天前,几小时前,几分钟前,几秒前)
    JavaScrip操作Cookie
    JS生成GUID算法
    老李推荐: 第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例 4
    老李推荐: 第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例 3
  • 原文地址:https://www.cnblogs.com/flix/p/13341860.html
Copyright © 2020-2023  润新知