leetcode36 - Valid Sudoku - medium


Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
1. Each row must contain the digits 1-9 without repetition.
2. Each column must contain the digits 1-9 without repetition.
3. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

 

1.brute force O(n^3)。
对每个有数字的格子,去检查横竖方有没有冲突。

2.模拟法 O(n^2)。
重点在于i嵌套j分别从0~8的时候,i动得慢,j动得快,怎么数学处理i,j,制造真正应用的下标,从而让下标的运动轨迹变成你想要的横扫描,列扫描,块扫描。
横扫描:board[i][j],固定行的时候变列数。
列扫描:board[j][i], 固定列的时候变行数。
块扫描: board[i / 3 * 3 + j / 3 ][i % 3 *3 + j % 3 ],i变换出九个块的起始坐标(0,0)(0,3)(0,6)(3,0)...,j变换出九个块的扫描偏移坐标(0,0)(0,1)(0,2)(1,0)...

细节:
1.块扫描的坐标变化里,i/3*3是一种把粒度降低缓慢变化的感觉,i从0~8的变化中,这个会按000333666来变化,j/3是000111222,两者合并用于变化行坐标。
i%3*3是一种快速突变但循环的感觉,i从0~8的变化中,这个会按036036036来变化,j%3是012012012,两者合并用于变化列坐标。
2.三个set在i循环内部初始化。因为要检查新一行/列/方块了
3.这题写的二重循环中,i j的意义不再是纵坐标,横坐标了,而是第几轮扫描,该轮扫描内的偏移辅助指针。
4.检查set是否存在当前对象前,要先预判是不是为空格子,只对非空数字做有意义的判断。

 

实现:

class Solution {
    public boolean isValidSudoku(char[][] board) {
        // P1: 注意要先预判是不是为空格子,要是空格子以前出现过同样的空格子结果你判出现重复了,那不是很蠢。
        
        for (int i = 0; i < 9; i++) {
            Set<Character> row = new HashSet<>();
            Set<Character> col = new HashSet<>();
            Set<Character> cube = new HashSet<>();
            for (int j = 0; j < 9; j++) {
                // scan row
                if (board[i][j] != '.' && !row.add(board[i][j])) {
                    return false;
                }
                // scan col
                if (board[j][i] != '.' && !col.add(board[j][i])) {
                    return false;
                }
                // scan cube
                int x = i / 3 * 3 + j / 3, y = i % 3 * 3 + j % 3;
                if (board[x][y] != '.' && !cube.add(board[x][y])) {
                    return false;
                }
            }
        }
        return true;
    }
}

 

转载于:https://www.cnblogs.com/jasminemzy/p/9660294.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值