[leetcode] Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

A sudoku solution must satisfy all of the following rules:

  • Each of the digits 1-9must occur exactly once in each row.
  • Each of the digits 1-9 must occur exactly once in each column.
  • Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.
A sudoku puzzle...
A sudoku puzzle…
...and its solution numbers marked in red.
…and its solution numbers marked in red.
Note:

  • The given board contain only digits 1-9 and the character '.'.
  • You may assume that the given Sudoku puzzle will have a single unique solution.
  • The given board size is always 9x9.

Solution

class Solution {
 public:
  void solveSudoku(vector<vector<char>>& board) {
    bool rows[9][9] = {0};
    bool columns[9][9] = {0};
    bool subBoxs[9][9] = {0};
	//标记每一行,每一列, 每一个9宫格中已经存在的数字,便于判断。
    for (int i = 0; i < board.size(); ++i) {
      for (int j = 0; j < board.size(); ++j) {
        if (board[i][j] > '0' && board[i][j] <= '9') {
          rows[i][board[i][j] - '1'] = 1;
          columns[j][board[i][j] - '1'] = 1;
          subBoxs[(i / 3) * 3 + j / 3][board[i][j] - '1'] = 1;
        }
      }
    }
    solve(board, rows, columns, subBoxs);
  }

  bool solve(vector<vector<char>>& board, bool (&rows)[9][9],
             bool (&columns)[9][9], bool (&subBoxs)[9][9]) {
    //这个地方还可以优化,避免不必要的查找'.'
    for (int i = 0; i < board.size(); ++i) {
      for (int j = 0; j < board.size(); ++j) {
        if (board[i][j] == '.') {
          //依次尝试1-9。
          for (int c = 0; c < board.size(); ++c) {
            if (!rows[i][c] && !columns[j][c] &&
                !subBoxs[(i / 3) * 3 + j / 3][c]) {
              board[i][j] = c + '1';
              rows[i][c] = 1;
              columns[j][c] = 1;
              subBoxs[(i / 3) * 3 + j / 3][c] = 1;
              //成功返回true
              if (solve(board, rows, columns, subBoxs)) {
                return true;
              }
              //失败还原
              rows[i][c] = 0;
              columns[j][c] = 0;
              subBoxs[(i / 3) * 3 + j / 3][c] = 0;
              board[i][j] = '.';
            }
          }
          //0-9全部失败,返回上一层递归。
          return false;
        }
      }
    }
    // 找不到'.'了,证明已经完成了数独的求解。
    return true;
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值