&LeetCode36& 有效的数独

题目

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
&LeetCode36& 有效的数独_第1张图片
上图是一个部分填充的有效的数独。
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

示例 1:
输入:
&LeetCode36& 有效的数独_第2张图片
输出: true

示例 2:
输入:
&LeetCode36& 有效的数独_第3张图片
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
给定数独序列只包含数字 1-9 和字符 '.' 。
给定数独永远是 9x9 形式的。

来源:力扣(LeetCode)

思路

使用 HashSet 来记录已经存在过的状态;
首先,将每个状态编码成为一个字符串;
其次,对于每个1到9内的数字来说,其在每行每列和每个小区间内都是唯一的;
再次,将数字放在一个括号中,每行上的数字就将行号放在括号左边,每列上的数字就将列数放在括号右边,每个小区间内的数字就将在小区间内的行列数分别放在括号的左右两边;
这样每个数字的状态都是独一无二的存在,就可以在 HashSet 中查找是否有重复存在了。

C++代码

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) 
    {
        unordered_set<string> st;
        for (int i = 0; i < 9; ++i) 
        {
            for (int j = 0; j < 9; ++j) 
            {
                if (board[i][j] == '.') 
                    continue;
                    
                string t = "(" + to_string(board[i][j]) + ")";

                string row = to_string(i) + t;
                string col = t + to_string(j);
                string cell = to_string(i / 3) + t + to_string(j / 3);

                if (st.count(row) || st.count(col) || st.count(cell)) 
                    return false;

                st.insert(row);
                st.insert(col);
                st.insert(cell);
            }
        }
        return true;
    }
};

你可能感兴趣的:(LeetCode)