最近看了一两篇关于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这个参数即为数独矩阵