为什么我的代码在leetcode中效果很好,而我的代码给出时间限制?

发布于 2025-02-04 17:37:18 字数 2982 浏览 1 评论 0原文

ref: https://leetcode.com/problems/problems/word-word-word-word-word-word-搜索/提交/

简短的问题语句:给出了字符和字符串的矩阵,该字符串是否存在于此矩阵中。请参阅上述链接以获取详细信息。

solution-1 给出超过时间限制。

class Solution {
public:
    int n;
    int m;
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for(auto d: dir){
            bool temp = search(board, w+1, i + d[0], j + d[1]);
            if(temp) return true;
        }
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};

解决方案2 正常工作。实际上,比C ++提交的〜93%快

class Solution {
public:
    int n;
    int m;
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        if(search(board, w+1, i -1, j) || search(board, w+1, i+1, j) || search(board, w+1, i, j-1) || search(board, w+1, i, j+1)) return true;
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};

这两个解决方案之间的唯一区别是我在搜索功能中递归称呼搜索功能的方式。

解决方案1 ​​中,它是:

vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for(auto d: dir){
    bool temp = search(board, w+1, i + d[0], j + d[1]);
    if(temp) return true;
}

solude-2 中,它是:

if(search(board, w+1, i -1, j) || search(board, w+1, i+1, j) || search(board, w+1, i, j-1) || search(board, w+1, i, j+1)) return true;

我认为第二个解决方案就像循环展开,而这部分解释了为什么第二个解决方案比第二个解决方案更快地第一个。这不是只有一个恒定的因素而更快。我的意思是渐近,它们是相似的。我感到惊讶的是,循环展开导致我的解决方案从TLE转变到93%的解决方案。

基本上,我的问题是,循环展开第二个解决方案如此之快的唯一原因,还是我缺少某些东西?

Ref: https://leetcode.com/problems/word-search/submissions/

Brief problem statement: Given a matrix of characters and a string, does the string exist in this matrix. Please refer the above link for details.

Solution-1 Gives time-limit exceeded.

class Solution {
public:
    int n;
    int m;
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for(auto d: dir){
            bool temp = search(board, w+1, i + d[0], j + d[1]);
            if(temp) return true;
        }
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};

Solution-2 Works fine. In fact faster than ~93 % of C++ submissions

class Solution {
public:
    int n;
    int m;
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        if(search(board, w+1, i -1, j) || search(board, w+1, i+1, j) || search(board, w+1, i, j-1) || search(board, w+1, i, j+1)) return true;
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};

The only difference between these two solutions is the way I call the search function recursively within the search function.

In the solution-1 it is:

vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for(auto d: dir){
    bool temp = search(board, w+1, i + d[0], j + d[1]);
    if(temp) return true;
}

In solution-2 it is:

if(search(board, w+1, i -1, j) || search(board, w+1, i+1, j) || search(board, w+1, i, j-1) || search(board, w+1, i, j+1)) return true;

I think the second solution is like loop unrolling and while this partly explains why the second one is faster than the first one. Isn't it faster by only a constant factor. I mean asymptotically they are similar. I am just surprised that loop unrolling is causing my solution to go from TLE to faster than 93% solutions.

Basically, my question is, Is loop unrolling the only reason why the second solution is so fast, or am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

音盲 2025-02-11 17:37:18

我不确定auto类型的时间复杂性!但是,如果您从递归函数中删除了2D矢量构造,而不是auto使用基于普通索引的循环访问向量,则您将通过TimeLimit。

class Solution {
public:
    int n;
    int m;
    vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        
        for(int r=0; r<4; r++){
            bool temp = search(board, w+1, i + dir[r][0], j + dir[r][1]);
            if(temp) return true;
        }
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};

I am not sure about the time complexity of auto type! But if you remove the 2D vector construction from the recursive function, and instead of auto use the normal index-based loop to access the vector then you would pass the timelimit.

class Solution {
public:
    int n;
    int m;
    vector<vector<int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    bool search(vector<vector<char>>& board, const char* w, int i, int j){
        
        if(i < 0 || i >= m || j < 0 || j >= n || *w != board[i][j] || board[i][j] == '\0') return false;
        if(*(w+1) == '\0') return true;

        char t = board[i][j];
        board[i][j] = '\0';
        
        for(int r=0; r<4; r++){
            bool temp = search(board, w+1, i + dir[r][0], j + dir[r][1]);
            if(temp) return true;
        }
        board[i][j] = t;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        m = board.size();
        n = board[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(search(board, word.c_str(), i, j)) return true;
            }
        }
        return false;
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文