Leetcode37题耗时以及内存占用问题
来源:8-8 回溯法是经典人工智能的基础 N Queens
Ian_Song
2020-03-26
老师您好,我的思路和您在github上的代码大体上差不多,我自己感觉有下面一些不同:
- 我对于递归到预先填好项的结果的处理是返回下一次递归的结果,您是直接跳过这些项
- 我的几个查找表写成了类的数据成员
- 几个小运算我写成了函数,包括算在box查找表里的index以及求下一次递归要运算的坐标
然而我的这一版代码比您的要慢一倍,空间上多消耗了近三倍内存。在我看来,我们使用了三个一样的查找表,为什么空间上会多出三倍的消耗呢?您能给我一些指点吗?
代码如下:
class Solution {
vector< vector<bool> > row;
vector< vector<bool> > col;
vector< vector<bool> > box;
public:
void solveSudoku(vector<vector<char>>& board) {
// initialize the charts
row = vector< vector<bool> > ( 9, vector<bool>(10, false) );
col = vector< vector<bool> > ( 9, vector<bool>(10, false) );
box = vector< vector<bool> > ( 9, vector<bool>(10, false) );
for( int i = 0; i < 9; i++ ){
for( int j = 0; j < 9; j++ ){
if( board[i][j] != '.' ){
int n = board[i][j] - '0';
int bI = boxIdx(i, j);
row[i][n] = true;
col[j][n] = true;
box[bI][n] = true;
}
}
}
assert( helper(board, 0, 0) );
}
private:
bool helper(vector<vector<char>>& board, int x, int y){
if( x == 9 )
return true;
int bI = boxIdx(x, y);
int newX = next(x, y)[0];
int newY = next(x, y)[1];
if( board[x][y] != '.' )
return helper(board, newX, newY);
for( int i = 1; i <= 9; i++ ){
if( row[x][i] == true )
continue;
if( col[y][i] == true )
continue;
if( box[bI][i] == true )
continue;
row[x][i] = true;
col[y][i] = true;
box[bI][i] = true;
board[x][y] = '0' + i;
bool res = helper(board, newX, newY);
if( res == true )
return true;
board[x][y] = '.';
row[x][i] = false;
col[y][i] = false;
box[bI][i] = false;
}
return false;
}
// return idx in box,[0, 9)
int boxIdx(int i, int j){
int boxI = i / 3;
int boxJ = j / 3;
return boxI * 3 + boxJ;
}
vector<int> next(int i, int j){
assert( j >= 0 && j < 9 );
if( j == 8 )
return { i + 1, 0 };
else
return { i, j + 1 };
}
};
写回答
1回答
-
因为你的递归层次比我的代码高。
在你的代码中,递归层次是稳定的 81 层。因为对于每一个新的位置,不管是不是 '.',都会递归下去。
但是对于我的代码,只有在 board[x][y] == '.' 的时候,才会尝试填写一个数,然后递归下去。所以,如果需要填写的数字很少的话,我的代码的递归层数也会很少:)
不过其实,我倒觉得这无所谓,我的觉得你的代码的思路挺清晰的:)
继续加油!:)
012020-03-27
相似问题