【问题标题】:TLE in Word Search backtracking单词搜索回溯中的 TLE
【发布时间】:2021-11-29 09:22:55
【问题描述】:

这是来自 Leetcode 的一个问题: 给定一个 m x n 的字符板网格和一个字符串单词,如果单词存在于网格中,则返回 true。 单词可以由顺序相邻单元格的字母构成,其中相邻单元格水平或垂直相邻。同一个字母单元格不能多次使用。

我用 dfs 做了简单的回溯,这是我的代码:

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int index = 0;
        for(int i = 0; i < board.size(); i++) {
            for(int j = 0; j < board[0].size(); j++) {
                if(existsUtil(board, index, word, i, j))
                    return true;
            }
        }
    
        return false;
    }
    bool existsUtil(vector<vector<char>> board, int index, string word, int i, int j) {
        if(index >= word.length())
            return true;
        if(i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[index] || board[i][j] == '0')
            return false;

        char temp = board[i][j];
        board[i][j] = '0';
        index += 1;
        bool value = existsUtil(board, index, word, i + 1, j) || existsUtil(board, index, word, i, j - 1) || existsUtil(board, index, word, i - 1, j) || existsUtil(board, index, word, i, j + 1);
        board[i][j] = temp;
    
        return value;
    }
};

此代码为更大的输入提供 TLE。但是在dfs函数中,如果我通过referece传递board参数,即如果我传递vector&lt;vector&lt;char&gt;&gt; &amp;board,则通过所有测试用例。为什么会这样?

【问题讨论】:

  • 你必须通过引用existsUtil来传递板,因为你正在改变它的内容:board[i][j] = temp;,如果你通过值传递它,将会制作一个板的副本并在副本上进行更改。 (learncpp.com/cpp-tutorial/passing-arguments-by-value)
  • 你最喜欢的 C++ 书籍对引用传递和值传递有何看法?
  • vector&lt;vector&lt;T&gt;&gt; 由于空间局部性差,可能会很慢。每个vector 包含一个单独的内存块,它可能不在其他vectors 包含的块附近,从而降低了缓存的有效性。考虑使用the one described in this answer 之类的矩阵

标签: c++ algorithm pass-by-reference depth-first-search recursive-backtracking


【解决方案1】:
  1. 我猜,您可以对代码进行一项优化,仅从 (words[i][j] == word[0]) 的位置开始 dfs

  2. 每次在递归调用中创建一个新的二维数组副本时,通过值传递时,第二次回答您的问题,从而提供 TLE。

  3. 查看我的比 100% 更快的 JAVA 代码,希望对您有所帮助!

class Solution {
    boolean flag = false;
    public boolean exist(char[][] board, String word) {

        for(int i = 0;i < board.length;i++){
            for(int j = 0;j < board[0].length;j++){
                if(board[i][j] == word.charAt(0)){
                    backtrack(board,word,1,i,j);
                    if(flag) return true;
                }
            }
        }

        return false;
    }

    void backtrack(char[][] board, String word, int p, int row, int col){
        if(board[row][col] > 255)
            return;
        else if(p > word.length() - 1){
            //System.out.println(asf);
            flag  = true;
            return;
        }

        board[row][col] ^= 256;
        //up
        if(row > 0 && board[row-1][col] == word.charAt(p)) {
            backtrack(board, word, p + 1, row - 1, col);
        }
        //down
        if(row < board.length - 1 && board[row+1][col] == word.charAt(p))
            backtrack(board,word, p+1,row+1,col);
        //left
        if(col > 0 && board[row][col-1] == word.charAt(p))
            backtrack(board,word, p+1,row,col-1);
        //right
        if(col < board[0].length - 1 && board[row][col+1] == word.charAt(p))
            backtrack(board,word, p+1,row,col+1);

        board[row][col] ^= 256;

        return;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 2022-07-25
    相关资源
    最近更新 更多