• 【Valid Sudoku】cpp


    题目

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

    The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

    A partially filled sudoku which is valid.

    Note:
    A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

    代码

    class Solution {
    public:
    bool isValidSudoku(std::vector<std::vector<char> > &board)
            {
                int len = board.size();
                if (len != 9) return false;
                bool row_check[9];
                bool col_check[9];
                bool subBox_check[9];
                for (int row = 0; row < len; ++row)
                {
                    std::fill(row_check, row_check+9, false);
                    std::fill(col_check, col_check+9, false);
                    std::fill(subBox_check, subBox_check+9, false);
                    for (int col = 0; col < len; ++col)
                    {
                        if (!Solution::if_valid(board, row, col, row_check)){
                            return false;
                        }
                        if (!Solution::if_valid(board, col, row, col_check)){
                            return false;
                        }
                        if (!Solution::if_valid(board, 3*(row/3)+col/3, 3*(row%3)+col%3, subBox_check)){
                            return false;
                        }
                    }
                }
                return true;
            }
    static bool if_valid(std::vector<std::vector<char> > &board, int x, int y, bool (&some_check)[9])
            {
                if (board[x][y]=='.'){
                    return true;
                }
                else{
                    if (some_check[board[x][y]-'1']){
                        return false;
                    }
                    else{
                        some_check[board[x][y]-'1'] = true;
                        return true;
                    }
                }
                return false;
            }
    };

    Tips

    1. 整体逻辑按照数独的要求走:

      a. 判断同一行

      b. 判断同一列

      c. 判断所在的sub box

    2. 判断时主要利用的数据结构是类似HashSet,由于三类判断条件类似,因此单独提出来一段代码。

    3. 一点儿技巧:这里时间复杂度没有什么可说的就是O(n²);可以做些文章的地方就是代码复杂度,如何遍历一次for..for...就判断完成全部的逻辑。

      a. 这里的核心就在于数独是对称的矩阵,行列对称;因此,行列坐标互换就可以走一次for...for...就完成1.a和1.b的判断逻辑。

      b. 这里还需要注意的是,for..for..中走完一列,则需要判断一个sub box是否valid;因此,需要将某一列的坐标映射到某个sub box上。搞清楚这一点就可以推理处坐标变换的公式。

    4. 在离线测试的时候,处理c++的 vector 二维字符数组还是非常不熟练,由Python转成cpp刷题确实不太习惯。后面在刷到string的题目时候,再把这cpp这部分强化一下。

    ==================================================

    第二次过这道题,第一次没有AC还是错在了sub matrix小方块的检验上面。

    class Solution {
    public:
        bool isValidSudoku(vector<vector<char>>& board) {
                for ( int i=0; i<board.size(); ++i )
                {
                    // check row
                    vector<bool> row_used(9,false);
                    for ( int j=0; j<board[i].size(); ++j )
                    {
                        if ( board[i][j]!='.' )
                        {
                            if ( row_used[board[i][j]-'1'] ) return false;
                            row_used[board[i][j]-'1'] = true;
                        }
                    }
                    // check col
                    vector<bool> col_used(9,false);
                    for ( int j=0; j<board.size(); ++j)
                    {
                        if ( board[j][i]!='.')
                        {
                            if ( col_used[board[j][i]-'1'] ) return false;
                            col_used[board[j][i]-'1'] = true;
                        }
                    }
                    // check sub matrix
                    vector<bool> subm_used(9,false);
                    for ( int j=0; j<board[i].size(); ++j )
                    {
                        int row = 3*(i/3) + j/3;
                        int col = 3*(i%3) + j%3;
                        if ( board[row][col]!='.' )
                        {
                            if ( subm_used[board[row][col]-'1'] ) return false;
                            subm_used[board[row][col]-'1'] = true;
                        }
                    }
                }
                return true;
        }
    };

    tips:

    这个要记住了
    row = 3*(i/3) + j/3

    col = 3*(i%3) + j%3

  • 相关阅读:
    JavaScript 检测浏览器更多信息【每日一段代码66】
    JavaScript throw 声明【每日一段代码64】
    JavaScript 计时器2 【每日一段代码73】
    JavaScript 按钮动画【每日一段代码70】
    JavaScript 检测浏览器【每日一段代码67】
    JavaScript 使用计时事件制作的钟表 【每日一段代码76】
    一个实现恢复删除机制(do undo)的设计
    基于邻接表的广度优先搜索遍历
    HDU1045 Fire Net
    深度遍历
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4456871.html
Copyright © 2020-2023  润新知