LeetCode 37. Sudoku Solver (回溯法) C++

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-9 must 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 ‘.’.

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。

在这里插入图片描述
在这里插入图片描述
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.

注意:
给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

C++

class Solution {
public:
	bool rows[9][9] = {false};
	bool cols[9][9] = {false};
	bool boxes[9][9] = {false};
    void solveSudoku(vector<vector<char>>& board) {
        for(int i = 0; i < 9; i++){
        	for(int j = 0; j < 9; j++){
        		if(board[i][j] != '.'){
        			rows[i][ board[i][j] - '1' ] = true; 
        			cols[j][ board[i][j] - '1' ] = true;
        			boxes[ (i/3)*3 + j/3 ][ board[i][j] - '1' ] = true; 
				}
			}
		}
		backtrack(board, 0, 0);
    }
    bool backtrack(vector<vector<char>>& board, int row, int col){
    	while(board[row][col] != '.'){
    		col++;
			if( col >= 9){
				col = 0;
				row++;
			}
			if(row >=9 ){
				return true;
			}
		}
		
		for(int i = 0; i < 9 ; i++){
			//限制编程 Constraint Programming
			if(rows[row][i] || cols[col][i] || boxes[ (row/3)*3 + col/3 ][i]){
				continue;
			}
			board[row][col] = i + '1';
			rows[row][i] = cols[col][i] = boxes[ (row/3)*3 + col/3 ][i] = true;
			if(backtrack(board,row,col)){
				return true;
			}
			//回溯 backtrack
			else{
				rows[row][i] = cols[col][i] = boxes[ (row/3)*3 + col/3 ][i] = false;
				board[row][col] = '.';
			}
		}
		return false;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值