【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/

posted @ 2020-07-19 22:53  Flix  阅读(254)  评论(0编辑  收藏  举报