LeeCode 79. 单词搜索

难度:中等。
标签:

开始因为一些小问题,错了两次,错误用例如下:
[“a”]
“a”

[“a”, “a”]
“aa”

修改之后超时了,代码如下:

class Solution {

    int a[4][4] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

    bool backtrace(vector<vector<char>> board, int m, int n, 
                    string word, int k, vector<pair<int, int>> path){
        if(k == word.size() - 1 && board[m][n] == word[k]){
            return true;
        }
        if(word[k] != board[m][n])return false;
        
        for(int i = 0; i < 4; i++){
            if(m + a[i][0] >= 0 && m + a[i][0] < board.size() && 
                n + a[i][1] >= 0 && n + a[i][1] < board[0].size()){
                int flag = 0;
                for(int k = 0; k < path.size(); k++){
                    if(path[k].first == m + a[i][0] && path[k].second == n + a[i][1]){
                        flag = 1;
                        break;
                    }
                }
                if(flag)continue;
                path.emplace_back(m, n);
                if(backtrace(board, m + a[i][0], n + a[i][1], word, k + 1, path)){
                    return true;
                }
                path.pop_back();
            }
        }
        return false;
    }


public:
    bool exist(vector<vector<char>>& board, string word) {
        vector<pair<int, int>> path;
        for(int i = 0; i < board.size(); i++){
            for(int j = 0; j < board[0].size(); j++){
                if(backtrace(board, i, j, word, 0, path))return true;
            }
        }
        return false;
    }
};

超时的用例:
[[“A”,“A”,“A”,“A”,“A”,“A”],[“A”,“A”,“A”,“A”,“A”,“A”],[“A”,“A”,“A”,“A”,“A”,“A”],[“A”,“A”,“A”,“A”,“A”,“A”],[“A”,“A”,“A”,“A”,“A”,“A”],[“A”,“A”,“A”,“A”,“A”,“A”]]
“AAAAAAAAAAAAAAB”

使用一个与board相同大小的数组来记录每个点是否被访问过,代码如下:

class Solution {

    int a[4][4] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
    
    bool backtrace(vector<vector<char>> board, int m, int n, 
                    string word, int k, vector<vector<int>>& visited){
        if(word[k] != board[m][n])return false;
        if(k == word.size() - 1){
            return true;
        }
        visited[m][n] = 1;
        for(int i = 0; i < 4; i++){
            int mm = m + a[i][0], nn = n + a[i][1];
            if(mm >= 0 && mm < board.size() && nn >= 0 && nn < board[0].size()){
                if(visited[mm][nn])continue;
                if(backtrace(board, mm, nn, word, k + 1, visited)){
                    return true;
                }
            }
        }
        visited[m][n] = 0;
        return false;
    }


public:
    bool exist(vector<vector<char>>& board, string word) {
        vector<vector<int>> visited(board.size(), vector<int>(board[0].size()));
        for(int i = 0; i < board.size(); i++){
            for(int j = 0; j < board[0].size(); j++){
                if(backtrace(board, i, j, word, 0, visited))return true;
            }
        }
        return false;
    }
};

不知道为什么还是超时,目前的代码与题解的代码几乎没什么区别了。

最后!试了很久,发现是因为传入参数 b o a r d board board时,没有使用取地址符号。在使用回溯法时,因为会递归调用函数,使用取地址符可以直接访问原始数据,若不使用就会创建很多临时变量,损耗了内存,浪费了时间。

正确代码:

class Solution {

    int a[4][4] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
    
    bool backtrace(vector<vector<char>>& board, int m, int n, 
                    string word, int k, vector<vector<int>>& visited){
        if(word[k] != board[m][n])return false;
        if(k == word.size() - 1){
            return true;
        }
        visited[m][n] = 1;
        for(int i = 0; i < 4; i++){
            int mm = m + a[i][0], nn = n + a[i][1];
            if(mm >= 0 && mm < board.size() && nn >= 0 && nn < board[0].size()){
                if(visited[mm][nn])continue;
                if(backtrace(board, mm, nn, word, k + 1, visited)){
                    return true;
                }
            }
        }
        visited[m][n] = 0;
        return false;
    }


public:
    bool exist(vector<vector<char>>& board, string word) {
        vector<vector<int>> visited(board.size(), vector<int>(board[0].size()));
        for(int i = 0; i < board.size(); i++){
            for(int j = 0; j < board[0].size(); j++){
                if(backtrace(board, i, j, word, 0, visited))return true;
            }
        }
        return false;
    }
};

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值