leetcode刷题随笔&数独是否合法&利用dfs求数独的解

最近看了一两篇关于leetcode刷题的总结,大体意思就是尽量不要使用ide(lll¬ω¬)然后默写代码保证bug free,这tm就让人很蒙蔽了,lz一直是用visual studio ,有时候程序跑崩了还用用单步调试,看来以后要改变自己的编程习惯了,是有些过分依赖ide了。以后每道题都尽量写一篇随笔把,谈谈对这题的感受,以后没准复习还能用得上。lz最近是电脑进水,项目就暂时不写了才有时间来刷leetcode,以后电脑修好之后也保证每日一题吧。


这次的题目是-->数独是否是合法的

不用管是否有解,就看已知的这堆数是否合法就行,也就是保证每一行一列一个3*3的小格里面不能有重复即可。

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.


A partially filled sudoku which is valid.

Note:

A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

空的地方是 . (点)

大概思路就是申请9*3=27个hash表 unordered_map  然后往里面塞数,如果出现重复就return false

发现速度挺慢的,就改成了申请3个 int [9][9] ,初值为0,如果有数就+1,比上面快了一点点。

class Solution {
public:
	 bool isValidSudoku(vector<vector<char>>& board) {
		 int mi[9][9] = { 0 }, mj[9][9] = { 0 }, mg[9][9] = { 0 };

		 for (int i = 0; i < 9; i++)
		 {
			 for (int j = 0; j < 9; j++)
			 {
				 if (board[i][j] != '.')
				 {
					 int index = board[i][j] - '0'-1;
					 if (mi[i][index] == 0 && mj[j][index] == 0 && mg[i / 3 * 3 + j / 3][index] == 0)
					 {
						 mi[i][index] = 1;
						 mj[j][index] = 1;
						 mg[i / 3 * 3 + j / 3][index] = 1;
					 }
					 else return false;
				 }

			 }
		 }
		 return true;
	 }
};

runtime 22ms

之前用hash是33ms

用时27min做完这题


第二道题是解数独,这次可坑死了,做了足足90min,主要是没想到会这么复杂,一开始就想的很简单,就以为可以填数的空位总会存在一个唯一解,然后解了这个又会出现别的唯一解,最后就能求了。然后花了一个小时写完发现程序出现死循环了,但我坚持没有用debug,靠眼睛调试觉得出现了不是唯一解的情况,果然自己亲自解了一下数独发现确实如此。于是看了一下discuss,发现别人的解析是用的dfs....emmm,那就用dfs写了,然后做出来了。runtime是5ms,只有6个测试样例。

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

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.


class Solution {
public:
	 void solveSudoku(vector<vector<char>>& board) {
		 int mi[9][9] = { 0 }, mj[9][9] = { 0 }, mg[9][9] = { 0 };
		 int count = 81;
		 for (int i = 0; i < 9; i++)
		 {
			 for (int j = 0; j < 9; j++)
			 {
				 if (board[i][j] != '.')
				 {
					 int index = board[i][j] - '0'-1;
					 mi[i][index] = 1;
					 mj[j][index] = 1;
					 mg[i / 3 * 3 + j / 3][index] = 1;
					 count--;
				 }
			 }
		 }	
		 dfs(board, mi, mj, mg, 0, 0);
	 }
	 bool dfs(vector<vector<char>> &board, int mi[9][9],int mj[9][9],int mg[9][9],int i,int j)
	 {
		 if (j == 9 && i == 8) return true;
		 if (j == 9) {
			 j = 0; i++;
		 }
		 if (board[i][j] != '.') return dfs(board, mi, mj, mg, i, j + 1);
		 for (int p = 0; p < 9; p++)
		 {
			 if (0 == mi[i][p] && 0 == mj[j][p] && 0 == mg[i / 3 * 3 + j / 3][p])
			 {
				 mi[i][p] = 1;
				 mj[j][p] = 1;
				 mg[i / 3 * 3 + j / 3][p] = 1;
				 board[i][j] = p + '0' + 1;
				 if (dfs(board, mi, mj, mg, i, j + 1))
					 return true;
				 else
				 {
					 mi[i][p] = 0;
					 mj[j][p] = 0;
					 mg[i / 3 * 3 + j / 3][p] = 0;
					 board[i][j] = '.';
				 }
			 }
		 } 
		 return false;
	 }
};

前面的与第一题差不多还是记录每行、每列、每个3*3格子的可用数字的状态,后面就是对每个为'.'的格子进行三个表的取交集,然后dfs就行了。注意别忘记判断false的情况。


顺便贡献一个测试样例,省的再敲了

	char *b[9] = { "..9748...","7........",".2.1.9...","..7...24.",".64.1.59.",".98...3..","...8.3.2.","........6","...2759..", };
	vector<vector <char> >  matrix;
	vector<char> row;

	for (int i = 0; i < 9; i++) {
		row.clear();
		char *col = b[i];
		while (*col != '\0') {
			row.push_back(*col);
			col++;
		}
		matrix.push_back(row);
	}
	for (int i = 0; i < matrix.size(); i++) {
		vector<char> row = matrix[i];
		vector<char> ::iterator vi;
		for (vi = row.begin(); vi != row.end(); vi++) {
			cout << *vi;
			cout << ' ';
		}
		cout << endl;
	}

matrix这个参数即为数独矩阵

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值