leetcode36 有效的数独

💎题目描述

验证一个9x9的数独是否有效,遵循以下规则:

  1. 每行只能包含数字1-9,且每个数字只能出现一次。
  2. 每列只能包含数字1-9,且每个数字只能出现一次。
  3. 每个3x3的宫格(以粗实线分隔)只能包含数字1-9,且每个数字只能出现一次。 注意:
  • 一个有效的数独不一定是可解的。
  • 只需根据以上规则验证已填入的数字是否有效。
  • 空白格用'.'表示。

❓解题思路

💥哈希表解法

🥇1.表格划分

我们将上述图片中的9x9棋盘格划分为9个分块box,分别命名为box[0]~box[8],然后在每一个小box里面再进行分块board,那么81个位置我们表示为下图所示的

🥈2.如何来区分这些块上的特定位置呢?

我们用board[i][j]来进行表示,我们先看数字i,将其分为三排,我们可以看出0、1、2再第一排;3、4、5在第二排;6、7、8在第三排;那么如何用i来表示这三排呢?

首先来看0、1、2

(0//3)*3=0

(1//3)*3=0

(2//3)*3=0

此时我们假设这一排给定的数字都在box[0]

首先来看3、4、5

(3//3)*3=3

(4//3)*3=3

(5//3)*3=3

此时我们假设这一排给定的数字都在box[3]

首先来看6、7、8

(6//3)*3=6

(7//3)*3=6

(8//3)*3=6

此时我们假设这一排给定的数字都在box[6]

然后我们再来看列,我们可以看出0、1、2再第一列;3、4、5在第二列;6、7、8在第三列;那么如何用j来表示这三列呢?

之前我们已经假设了在某个box了,那么第一列就是加0,第二列就是加1,第三列就是加2

来看0、1、2

0//3=0

1//3=0

2//3=0

来看3、4、5

3//3=1

4//3=1

5//3=1

来看6、7、8

6//3=2

7//3=2

8//3=2

也就是(i//3)*3+j//3

🥉3.代码

🏆python完整代码
class Solution:
    def isValidSudoku(self, board):
        # 初始化三个列表,分别用于记录每行、每列和每个3x3框中出现的数字
        rows = [set() for _ in range(9)]  # 每行
        cols = [set() for _ in range(9)]  # 每列
        boxes = [set() for _ in range(9)]  # 每个3x3框

        # 遍历整个数独板
        for i in range(9):
            for j in range(9):
                # 如果当前格子不为空
                if board[i][j] != '.':
                    num = int(board[i][j])  # 将当前字符转换为数字
                    box_index = (i // 3) * 3 + j // 3  # 计算当前格子所属的3x3框的索引

                    # 检查当前数字是否已经出现在当前行、当前列或当前3x3框中
                    if num in rows[i] or num in cols[j] or num in boxes[box_index]:
                        return False  # 如果出现重复,返回False

                    # 将当前数字加入到相应的行、列和框的集合中
                    rows[i].add(num)
                    cols[j].add(num)
                    boxes[box_index].add(num)

        return True  # 如果整个数独板满足条件,则返回True


# 测试用例
if __name__ == "__main__":
    sol = Solution()
    # 给定的数独板
    board = [
        ["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"]
    ]
    # 打印结果
    print("是否是有效数独:", sol.isValidSudoku(board))
🏅c++完整代码 
#include<iostream>
#include<vector>
#include<unordered_set>

using namespace std;


class Solution{
public:
bool isValidSudoku(vector<vector<char>>& board){
    vector<unordered_set<char>> rows(9);// 用于记录每行中出现的数字的哈希表
    vector<unordered_set<char>> cols(9);// 用于记录每列中出现的数字的哈希表
    vector<unordered_set<char>> boxes(9); // 用于记录每个3x3框中出现的数字的哈希表

    for(int i=0;i<9;i++){ //遍历行
        for(int j=0;j<9;j++){ //遍历列
            char num = board[i][j];//获取当前格子的数字
            if(num != '.'){
                int box_index = (i/3)*3 + j/3;// 计算当前格子所属的3x3框的索引
                if(rows[i].count(num) || cols[j].count(num) || boxes[box_index].count(num)){
                    return false; // 如果当前数字已经在当前行、当前列或当前3x3框中出现过,则返回false
                }
                rows[i].insert(num); // 将当前数字加入到相应的行的哈希表中
                cols[j].insert(num); // 将当前数字加入到相应的列的哈希表中
                boxes[box_index].insert(num); // 将当前数字加入到相应的3x3框的哈希表中
            }
        }
    }
    return true;
}
};

int main(){
    Solution sol;
    vector<vector<char>> board = { // 给定的数独板
    {'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'}
};

    // 输出结果
    cout << "Is valid sudoku: " << boolalpha << sol.isValidSudoku(board) << endl;

    return 0;
}
🎖java完整代码 
import java.util.HashSet;
class isValidSudoku {
    public boolean isValidSudoku1(char[][] board) {
        HashSet<Character>[] rows = new HashSet[9]; // 用于记录每行中出现的数字的哈希表
        HashSet<Character>[] cols = new HashSet[9]; // 用于记录每列中出现的数字的哈希表
        HashSet<Character>[] boxes = new HashSet[9]; // 用于记录每个3x3框中出现的数字的哈希表

        // 初始化哈希表
        for (int i = 0; i < 9; i++) {
            rows[i] = new HashSet<Character>();
            cols[i] = new HashSet<Character>();
            boxes[i] = new HashSet<Character>();
        }

        // 遍历数独板
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char num = board[i][j];
                if (num != '.') { // 如果当前格子不为空
                    int box_index = (i / 3) * 3 + j / 3; // 计算当前格子所属的3x3框的索引
                    if (rows[i].contains(num) || cols[j].contains(num) || boxes[box_index].contains(num)) {
                        return false; // 如果当前数字已经在当前行、当前列或当前3x3框中出现过,则返回false
                    }
                    rows[i].add(num); // 将当前数字加入到相应的行的哈希表中
                    cols[j].add(num); // 将当前数字加入到相应的列的哈希表中
                    boxes[box_index].add(num); // 将当前数字加入到相应的3x3框的哈希表中
                }
            }
        }

        return true; // 如果整个数独板满足条件,则返回true
    }
}

// 测试用例
class Main {
    public static void main(String[] args) {
        isValidSudoku sol = new isValidSudoku();
        // 给定的数独板
        char[][] board = {
            {'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'}
        };
        // 输出结果
        System.out.println("Is valid sudoku: " + sol.isValidSudoku1(board));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长沙有肥鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值