第七周 Valid Sudoku

Valid Sudoku

LeetCode上的36题:https://leetcode.com/problems/valid-sudoku/

题目

判断一个9*9数独是否合理

Example1:

Input:
[
  ["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"]
]
Output: true

Example2:

Input:
[
  ["8","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"]
]
Output: false
Explanation: Same as Example 1, except with the 5 in the top left corner being 
    modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.

数独合理即是可解,这里只要求检查填充的数字是否合理。一个可解的数独相同行列上没有同一个数字,每个字数独空间内不存在同一个数字。

9*9数独实例

题解

能简单想到的算法是遍历每一个填充的数字,对每一个数字,如果同一行或列中,或同一个子数独空间中有相同的数字,则数独不可解。然而这个算法时间复杂度高。
另一个好的算法是为每一个数字维护一个记录位置数组,每遍历一个数字就找其对应的数组,如果与数组中的一个数字的位置在同一行或列中,或同一个子数独空间中,说明数独不可解。否则将数字位置推入数组中。相比于对每一个数字遍历行列和子空间,这里只需要与先前记录的相同值做判断即可。

代码

class Solution {
    struct point {
        int x;
        int y;
        point(int x0, int y0) : x{x0}, y{y0} {};
    };
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        const int 
            _size = 9,
            m_size = 3;
        vector<vector<point>> record(_size);
        
        for (int x = 0; x < _size; x++) {
            for (int y = 0; y < _size; y++) {
                if (board[x][y] != '.') {
                    int value = board[x][y] - '0';
                    
                    if (record[value - 1].size()) {
                        for (auto &p : record[value - 1]) {
                            if (p.x == x || p.y == y 
                                || (p.x/m_size*m_size == x/m_size*m_size
                                && p.y/m_size*m_size == y/m_size*m_size))
                                return false;
                        }
                    }
                    
                    record[value - 1].push_back(point(x, y));
                }
            }
        }
        
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值