zoukankan      html  css  js  c++  java
  • 37. Sudoku Solver

    问题:

    数独问题,给定一个数独数组,求解填入数字,有且只有一个解。

    A sudoku solution must satisfy all of the following rules:
    
    Each of the digits 1-9 must occur exactly once in each row.
    Each of the digits 1-9 must occur exactly once in each column.
    Each of the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
    The '.' character indicates empty cells.
    
    Example 1:
    Input: board = [["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: [["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
    Explanation: The input board is shown above and the only valid solution is shown below.
    
    Constraints:
    board.length == 9
    board[i].length == 9
    board[i][j] is a digit or '.'.
    It is guaranteed that the input board has only one solution.
    

        ->    

    解法:Backtracking(回溯算法)

    参数:

    • path:board到目前为止填入的情况。
        • pos:当前位置 i,j
    • optionlists:1~9。(除去不合要求的数字,使用isValid进行check)

    处理:

      • 退出条件:if(遍历到9*9最后一个格子之后) 则标记已找到答案find=true,return
      • for所有可选项:opt=1~9 &&( isValid == true )
    • 做选择:board[i][j]=opt
    • 递归:
      • backtracking(board, pos+1) 
    • 撤销选择:board[i][j]='.'

    ⚠️ 特别的,isValid的判断方法:board中:

    • 在同一行中,没有冲突(与要填入的opt重复)
    • 在同一列中,没有冲突(与要填入的opt重复)
    • 在同一小方块中,没有冲突(与要填入的opt重复)
      • 找到所在小方块的↖️左上坐标:row=i-i%3, col=j-j%3

    代码参考:

     1 class Solution {
     2 public:
     3     bool find=false;
     4     void solveSudoku(vector<vector<char>>& board) {
     5         backtracking(board, 0);
     6     }
     7 
     8     void backtracking(vector<vector<char>>& board, int pos) {
     9         while(pos<(9*9) && board[pos/9][pos%9] != '.') pos++;
    10         if(pos==(9*9)) {
    11             find=true;
    12             return;
    13         }
    14         int i = pos/9, j = pos%9;
    15         for(char opt='1'; opt<='9'; opt++) {
    16             if(isValid(board, i, j, opt)) {
    17                 board[i][j] = opt;
    18                 backtracking(board, pos+1);
    19                 if(find) return;
    20                 board[i][j] = '.';
    21             }
    22         }
    23         return;
    24     }
    25     bool isValid(const vector<vector<char>>& board, int i, int j, char opt) {
    26         if(isRowConflict(board, i, j, opt)) return false;
    27         if(isColConflict(board, i, j, opt)) return false;
    28         if(isRecConflict(board, i, j, opt)) return false;
    29         return true;
    30     }
    31     
    32     bool isRowConflict(const vector<vector<char>>& board, int i, int j, char opt) {
    33         for(int jt = 0; jt < 9; jt++) {
    34             if(board[i][jt] == opt) return true;
    35         }
    36         return false;
    37     }
    38     bool isColConflict(const vector<vector<char>>& board, int i, int j, char opt) {
    39         for(int it = 0; it < 9; it++) {
    40             if(board[it][j] == opt) return true;
    41         }
    42         return false;
    43     }
    44     bool isRecConflict(const vector<vector<char>>& board, int i, int j, char opt) {
    45         int row = i-i%3;
    46         int col = j-j%3;//evey Rec ↖︎leftup cell pos
    47         for(int it = 0; it < 3; it++) {
    48             for(int jt = 0; jt < 3; jt++) {
    49                 if(board[row+it][col+jt] == opt) return true;
    50             }
    51         }
    52         return false;
    53     }
    54 };
  • 相关阅读:
    c++中为什么static成员函数不能声明为const
    VS 如何查看反汇编代码?
    Algorithm: 获取指定范围的随机数(包含范围临界值)
    Windows2003防黑客入侵:系统权限与安全配置
    nc使用方法
    突破安全狗的技术总汇
    入侵检测经验总结
    Temporary failure in name resolution:Illegal seek(转)
    各种在线编辑器漏洞
    Linux加固
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14223178.html
Copyright © 2011-2022 走看看