79 单词搜索

13 篇文章 0 订阅
7 篇文章 0 订阅

题目

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true
示例 3:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m=board.size(), n=board[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n,false));//记录当前节点是否被访问
        //遍历矩阵,判断以每一个节点为起点是否能匹配全部的单词
        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){
                if(dfs(board, visited, word, i, j, 0)) //如果匹配成功,返回true
                    return true;
            }
        }
        return false;//遍历完矩阵也没找到,就返回false
    }
private:
	//index表示当前要匹配word的index号字母
    bool dfs(vector<vector<char>>& board,vector<vector<bool>>& visited, const string& word, int x, int y, int index){
        if(index==word.size()) return true;//如果找到了完整的单词
        if(x<0 || y<0 || x>=board.size()||y>=board[0].size()) return false;//如果下标超过矩阵范围
        if(visited[x][y]) return false;//如果当前节点已经访问过
        if(board[x][y]!=word[index]) return false;//如果匹配失败
        //匹配成功
        visited[x][y] = true;
        //尝试四个方向
        bool resu= dfs(board, visited, word, x-1, y, index+1) || dfs(board, visited, word, x+1, y, index+1) || dfs(board, visited, word, x, y-1, index+1) || dfs(board, visited, word, x, y+1, index+1);
        visited[x][y] = false;//恢复原样
        return resu;//返回结果
    }
};
  • 时间复杂度O(n^2 *m^2)

  • 空间复杂度O(n^2)

  • 思路

    • 遍历矩阵,以每个点为起点,调用dfs,判断能否找到完全匹配的单词
    • dfs传入的参数有原矩阵,记录当前节点是否被访问的visited矩阵,单词word,当前节点的下标x,y以及当前搜索的是单词的第几个字母index
      • 递归边界是index等于单词的长度,表示找到了,返回true
      • 如果坐标超出矩阵范围,返回false
      • 如果当前节点已经被访问过,返回false
      • 如果当前节点的值与单词中index对应的字母不匹配,返回false
      • 否则,表示当前字母是匹配的,先将visited矩阵中的位置标为true,再递归调用dfs,搜索下一个字母,分别尝试四个方向,将结果记录在resu中
      • 将visited矩阵中的位置恢复为false,返回resu
  • 优化O(1)的空间复杂度

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m=board.size(), n=board[0].size();
        //优化掉了visited矩阵
        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){
                if(dfs(board, word, i, j, 0)) 
                    return true;
            }
        }
        return false;
    }
private:
	//把0作为标志,如果访问过该节点就将值改为0
    bool dfs(vector<vector<char>>& board, const string& word, int x, int y, int index){
        if(index==word.size()) return true;
        if(x<0 || y<0 || x>=board.size()||y>=board[0].size()) return false;
        if(board[x][y]=='0') return false;
        if(board[x][y]!=word[index]) return false;
        //匹配成功
        board[x][y] = '0';
        bool resu= dfs(board, word, x-1, y, index+1) || dfs(board, word, x+1, y, index+1) || dfs(board, word, x, y-1, index+1) || dfs(board, word, x, y+1, index+1);
        board[x][y] = word[index];//借助index还原原来的单词
        return resu;
    }
};
  • 如果当前节点已经访问过,就将它标记为‘0’,在全字母的矩阵中,如果该节点为1则表示已经访问
  • 匹配成功的话,借助word以及index将1再复原为原来的字母
  • 从而避免了使用visited矩阵
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值