【leetcode】有效的数独

本文介绍了如何利用哈希表、数组和位运算来判断数独的合法性。首先,通过哈希表分别遍历行、列和块来检查数字重复,然后使用数组优化遍历过程,最后提及了位运算的解决方案,虽然复杂但能进一步提高效率。文章提供了详细的代码实现和解释。
摘要由CSDN通过智能技术生成

解题关键

关键是:怎样判断某个格子的数字在哪个block块儿,数独总共有9个block块儿
在这里插入图片描述
图片引用:
https://leetcode-cn.com/problems/valid-sudoku/solution/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/

具体实现上,判断是否出现过可以用哈希表、数组、位运算

Solution 1: 哈希表

代码1:遍历三次

第1次遍历:遍历行
第2次遍历:遍历列
第3次遍历:遍历block
这样遍历三次,能不能一次遍历解决行、列、block的判断呢?

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """

        # for row
        for i in range(0,9):
            row = board[i]
            hash_row = dict()
            for j in range(0,9):
                if row[j]!= '.':
                    if row[j] in hash_row.keys(): # 判断字典是否存在关键字的语句
                        return False
                    else:
                        hash_row[row[j]] = j

        # for columns
        board_trans = [[row[i] for row in board] for i in range(len(board[0]))]
        for i in range(0,9):
            column = board_trans[i]
            hash_column = dict()
            for j in range(0,9):
                if column[j]!='.':
                    if column[j] in hash_column.keys(): 
                        return False
                    else:
                        hash_column[column[j]] = j
       
        # for block
        hash_block = dict()
        for i in range(0,9):
            hash_block[i] = dict()
        for i in range(0,9):
            for j in range(0,9):
                if board[i][j] != '.':
                    idx_block = int(i/3)*3 + int(j/3)
                    if board[i][j] in hash_block[idx_block].keys():
                        return False
                    else:
                        hash_block[idx_block][board[i][j]] = board[i][j] # 具体数值不重要,有数做标记
        return True

测试通过,运行成功

代码2:遍历一次

一次遍历过程中,分别去判断行是否满足要求、列是否满足要求、block是否满足要求,那么空间换时间的思想,建立哈希表数组
特别需要注意是,需要判断格子元素是’.‘的情况,如果格子元素是’.',那么什么都不做

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        col = [{} for i in range(0, 9)]
        row = [{} for i in range(0, 9)]
        block = [{} for i in range(0, 9)]

        for i in range(0, 9):
            for j in range(0, 9):
                if board[i][j] != '.':
                    if board[i][j] in row[i]:
                        return False
                    else:
                        row[i][board[i][j]] = 1
                    
                    if board[i][j] in col[j]:
                        print('col')
                        return False
                    else:
                        col[j][board[i][j]] = 1

                    
                    idx_block = 3 * (i//3) + (j//3)
                    if board[i][j] in block[idx_block]:
                        print('block')
                        return False
                    else:
                        block[idx_block][board[i][j]] = 1
        
        return True

Solution 2: 数组

用数组替代哈希表,因为哈希表的key值是[1,9],是数组的索引

虽然时间复杂度一样,但哈希表的更新和查询复杂度为均摊 O(1),而定长数组的的更新和查询复杂度则是严格 O(1)。(引用自参考链接:https://leetcode.cn/problems/valid-sudoku/solutions/1002073/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/)

但是从真实的时间来看,实际执行时间并没有比哈希表时间快,(ಥ﹏ಥ)

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
       
        # Solution 2: 数组作为哈希表
        col = [[0]*9 for i in range(0,9)]
        row = [[0]*9 for i in range(0,9)]
        block = [[0]*9 for i in range(0,9)]

        for i in range(0, 9):
            for j in range(0, 9):
                if board[i][j] != '.':

                    if row[i][int(board[i][j])-1] == 0:
                        row[i][int(board[i][j])-1] = 1
                    else:
                        return False

                    if col[j][int(board[i][j])-1] == 0:
                        col[j][int(board[i][j])-1] = 1
                    else:
                        return False

                    idx_block = 3 * (i//3) + (j//3)
                    if block[idx_block][int(board[i][j])-1] == 0:
                        block[idx_block][int(board[i][j])-1] = 1
                    else:
                        return False
        return True

Solution 3: 位运算

过于复杂,没有看懂,感兴趣的小伙伴可以参考下面链接中的大神讲解
https://leetcode.cn/problems/valid-sudoku/solutions/1002073/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值