36. 有效的数独Valid Sudoku/37. 解数独

版权声明:只要梦想一天,只要梦想存在一天,就可以改变自己的处境。 https://blog.csdn.net/dongyanwen6036/article/details/85855385

vector里面装bool类型,在<< Effective STL>> 这本书里有说明,最好不要在vector装bool类型。替换本文就好。

const int cnt = 9;
        bool rowFlag[cnt][cnt] = {false};
        bool colFlag[cnt][cnt] = {false};
        bool cellFlag[cnt][cnt] = {false};
36. 有效的数独Valid Sudoku

难度:easy

分析:
我们需要三个标志矩阵,分别记录各行,各列,各小方阵是否出现某个数字,
其中行和列标志下标很好对应,就是cell小方阵的下标需要稍稍转换一下。

if (rowFlag[i][c] || colFlag[c][j] || cellFlag[3 * (i / 3) + j / 3][c])
其实也就是满足三条:

  • 1.数字 1-9 在每一行只能出现一次。
  • 2.数字 1-9 在每一列只能出现一次。
  • 3.数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

[3 * (i / 3) + j / 3]画个图代表每一个小方阵从左到右,从上到下。
在这里插入图片描述

class Solution {
 public:
	 bool isValidSudoku(vector<vector<char>>& board) {
		 if (board.empty() || board[0].empty())return false;
		 int m = board.size(), n = board[0].size();
		 vector < vector<bool >>rowFlag(m, vector<bool>(n, false));
		 vector < vector<bool >>colFlag(m, vector<bool>(n, false));
		 vector < vector<bool >>cellFlag(m, vector<bool>(n, false));
		 for(int i=0;i<m;i++)
			 for (int j = 0; j < n; j++)
			 {
				 if (board[i][j] >= '1'&& board[i][j] <= '9')
				 {
					 int c = board[i][j] - '1';
					 if (rowFlag[i][c] || colFlag[c][j] || cellFlag[3 * (i / 3) + j / 3][c])
						 return false;
					 rowFlag[i][c] = true;
					 colFlag[c][j] = true;
					 cellFlag[3 * (i / 3) + j / 3][c] = true;
				 }
			 }
		 return true;
	 }
 };
37. 解数独,代码参考[2]

难度:hard
跟此题类似的
有 Permutations 全排列,
Combinations 组合项,
N-Queens N皇后问题等等,
其中尤其是跟 N-Queens N皇后问题的解题思路及其相似.

c++ code:

 class Solution {
 public:
	 bool rowFlag[9][9];
	 bool colFlag[9][9];
	 bool cellFlag[9][9];
	 void solveSudoku(vector<vector<char>>& board) {
		 if (board.size() != 9 || board[0].size() != 9)return;
		 int m = board.size(), n = board[0].size();
		 int c;	      
		 for (int i = 0; i<m; i++)//初始化
			 for (int j = 0; j < n; j++)
			 {
				 if (board[i][j] == '.')continue;
				 c = board[i][j] - '1';
				 rowFlag[i][c] = true;
				 colFlag[c][j] = true;
				 cellFlag[3 * (i / 3) + j / 3][c] = true;
			 }
		 DFsolve(board,0);
	 }
	 bool DFsolve(vector<vector<char>>& board,int pos)
	 {
		 int row = pos / 9;
		 int col = pos % 9;
		 if (pos > 80)return true;//finish

		 if (board[row][col] != '.')
		 {
			 return DFsolve(board,pos + 1);
		 }
		 for (int c = 0; c < 9; c++)
		 {
			 if (rowFlag[row][c] || colFlag[c][col] || cellFlag[3 * (row / 3) + col / 3][c])
				 continue;//找到满足的number
			 board[row][col] = (char)(c + '1');
			 rowFlag[row][c] = colFlag[c][col] = cellFlag[3 * (row / 3) + col / 3][c] = true;
			 if (DFsolve(board, pos + 1))
				 return true;
			 else
			 {//重新找
				 board[row][col] = '.';
				 rowFlag[row][c] = colFlag[c][col] = cellFlag[3 * (row / 3) + col / 3][c] = false;
			 }

		 }
		 return false;
	 }
 };

[1]https://segmentfault.com/a/1190000004309465
[2]https://segmentfault.com/a/1190000000457789

猜你喜欢

转载自blog.csdn.net/dongyanwen6036/article/details/85855385