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回答

liuyubobobo

2020-03-27

因为你的递归层次比我的代码高。


在你的代码中,递归层次是稳定的 81 层。因为对于每一个新的位置,不管是不是 '.',都会递归下去。


但是对于我的代码,只有在 board[x][y] == '.' 的时候,才会尝试填写一个数,然后递归下去。所以,如果需要填写的数字很少的话,我的代码的递归层数也会很少:)


不过其实,我倒觉得这无所谓,我的觉得你的代码的思路挺清晰的:)


继续加油!:)

0
1
Ian_Song
谢谢波波老师!我自己默认只有很少的一些数字是预置的,对于测试用例没考虑的不够全面了。
2020-03-27
共1条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程