LeetCode - 数独类题目总结

什么是数独

   数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复 [1] 。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。


在这里插入图片描述


有效的数独

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。数独部分空格内已填入了数字,空白格用 ‘.’ 表示。


在这里插入图片描述

示例 1: 输入:
[
[“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”]
]
输出: true

分析:遍历输入,检测每一行、列、子九宫格内出现的1~9的数字有没有重复即可。

class Solution {
public:
	bool isValidSudoku(vector<vector<char>>& board) {
		bool row [9][9]={false};   //row的index和num
		bool col [9][9]={false};	 //col的index和num
		bool block [9][9]={false}; //block的index和num
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				if (board[i][j] != '.') {
					int num = board[i][j] - '1';//数独中的1~9 在数组中作为0~8
					int blockindex = (i/ 3) * 3 + j / 3;
					if (row[i][num] || col[j][num] || block[blockindex][num])
						return false;
					row[i][num] = true;
					col[j][num] = true;
					block[blockindex][num] = true;
				}
			}
		}
		return true;
	}
};

解数独

编写一个程序,通过已填充的空格来解决数独问题。一个数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次, 数字 1-9 在每一列只能出现一次, 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

分析: 回溯递归 dfs

class Solution {
public:
	void solveSudoku(vector<vector<char>>& board) {
		bool row[9][9] = { false };   //row的index和num
		bool col[9][9] = { false };	 //col的index和num
		bool block[9][9] = { false }; //block的index和num
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				if (board[i][j] != '.') {
					int num = board[i][j] - '1';//数独中的1~9 在数组中作为0~8
					int blockindex = (i / 3) * 3 + j / 3;
					row[i][num] = true;
					col[j][num] = true;
					block[blockindex][num] = true;
				}
			}
		}
		dfs(board, row, col, block, 0, 0);
		printboard(board);
	}
	bool dfs(vector<vector<char>>& board, bool row[9][9], bool col[9][9], bool block[9][9], int rowindex, int colindex) {
		//从第一行开始向右寻找第一个为空的宫格。
		while (board[rowindex][colindex] != '.'&&rowindex<9&&colindex<9) {
			if (++colindex >= 9) {
				rowindex++;
				colindex = 0;
			}
			if (rowindex >= 9) {
				return true;
			}
		}
		for (int num = 0; num < 9; num++) {
			int blockIndex = rowindex / 3 * 3 + colindex/ 3;
			if (!row[rowindex][num] && !col[colindex][num] && !block[blockIndex][num]) {
				// 递归
				board[rowindex][colindex] = (char)('1' + num);
				row[rowindex][num] = true;
				col[colindex][num] = true;
				block[blockIndex][num] = true;
				if (dfs(board, row, col, block, rowindex, colindex)) {
					return true;
				}
				else {
					// 回溯
					row[rowindex][num] = false;
					col[colindex][num] = false;
					block[blockIndex][num] = false;
					board[rowindex][colindex] = '.';
				}
			}
		}
		return false;

	}
	void printboard(vector<vector<char>> board)
	{
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				cout << board[i][j] << " ";
			}
			cout << endl;
		}
	}
};
发布了76 篇原创文章 · 获赞 6 · 访问量 2775

猜你喜欢

转载自blog.csdn.net/u014618114/article/details/104163464