zoukankan      html  css  js  c++  java
  • LeetCode-36. Valid Sudoku

    一、问题描述

      判断一个不完整的数独是否正确。

      判断数独是否正确的条件:1、每行的数不重复。2、没列的数不重复。3、划分成的9个3*3的块中没有数重复。

      例子看下面代码中的测试用例。

    二、问题解决

      思路一:分3次循环来解决,第一次横向遍历,第二次纵向遍历,第三次以块遍历。每一次遍历一行、一列、或是一块的时候使用map记录每个数出现的次数,当出现两次的时候返回false

    bool isValidSudoku(vector<vector<char>>& board) {
        for (auto i : board) {
            map<char, int> map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
            { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
            for (auto j : i) {
                if (j == '.') continue;
                if (map[j] == 0)
                    map[j]++;
                else
                    return false;
            }
            map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
            { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
        }
    
        for (int i = 0; i < 9; i++) {
            map<char, int> map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
            { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
            for (int j = 0; j < 9; j++) {
                if (board[j][i] == '.') continue;
                if (map[board[j][i]] == 0)
                    map[board[j][i]]++;
                else
                    return false;
            }
            map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
            { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
        }
    
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                map<char, int> map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
                { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
                for (int m = 0; m < 3; m++) {
                    for (int n = 0; n < 3; n++) {
                        int posx = m + i * 3;
                        int posy = n + j * 3;
                        if (board[posx][posy] == '.') continue;
                        if (map[board[posx][posy]] == 0)
                            map[board[posx][posy]]++;
                        else
                            return false;
                    }
                }
                map = { { '1',0 },{ '2',0 },{ '3',0 },{ '4',0 },
                { '5',0 },{ '6',0 },{ '7',0 },{ '8',0 },{ '9',0 }, };
            }
        }
        return true;
    }
    
    int main()
    {
        vector<vector<char>> v = {{'.', '.', '.', '.', '5', '.', '.', '1','.'},
                                { '.', '4', '.', '3', '.', '.', '.', '.', '.' },
                                { '.', '.', '.', '.', '.', '3', '.', '.', '1' },
                                { '8', '.', '.', '.', '.', '.', '.', '2', '.' },
                                { '.', '.', '2', '.', '7', '.', '.', '.', '.' },
                                { '.', '1', '5', '.', '.', '.', '.', '.', '.' },
                                { '.', '.', '.', '.', '.', '2', '.', '.', '.' },
                                { '.', '2', '.', '9', '.', '.', '.', '.', '.' },
                                { '.', '.', '4', '.', '.', '.', '.', '.', '.' } };
        cout << isValidSudoku(v) << endl;
    
        system("pause");
        return 0;
    }

      思路二:更简洁方便的解决

    bool isValidSudoku(vector<vector<char> > &board)
        {
            int used1[9][9] = {0}, used2[9][9] = {0}, used3[9][9] = {0};
            
            for(int i = 0; i < board.size(); ++ i)
                for(int j = 0; j < board[i].size(); ++ j)
                    if(board[i][j] != '.')
                    {
                        int num = board[i][j] - '0' - 1, k = i / 3 * 3 + j / 3;
                        if(used1[i][num] || used2[j][num] || used3[k][num])
                            return false;
                        used1[i][num] = used2[j][num] = used3[k][num] = 1;
                    }
            
            return true;
        }

    三、问题总结

      在判断是否出现重复的时候使用9*9的数组来表示,而不是使用map。

      遍历一遍就ok了。

      在利用i和j计算块内索引的时候很巧妙,记住这种方法。

      大神的代码就是厉害。

  • 相关阅读:
    软件设计中的立足点
    Clojure基础
    团队凝聚力
    执行力与领导力
    工作与生活
    分离焦虑OR责任焦虑
    保持激情
    立足点
    论研发管理--开篇
    初级码农常犯错误
  • 原文地址:https://www.cnblogs.com/likaiming/p/8371079.html
Copyright © 2011-2022 走看看