【剑指offer】11.矩阵中的路径(单词搜索)

题目

在这里插入图片描述
LeetCode链接

分析

这是一个可以用回溯法解决的典型题。

判断是否存在指定的单词,也就是判断是否有一条为对应word的路径

首先在矩阵中任选一个格子作为路径的起点。如果矩阵中的该格子恰好是word中的第i个字符。那么到相邻的格子上寻找路径上的第i+1个字符。除了矩阵边界上的格子,每个都有四个相邻的格子。重复这个过程直到路径上的所有字符都在矩阵中找到相应的位置

由于回溯的递归特性,路径可以看做是一个栈。
当在矩阵中定位好前n个字符的位置之后,如果在第n个字符对应的格子周围都没有找到第(n+1)个单词,这时候在路径上回到第n-1个字符。重新定位第n个字符。

由于路径不能重复进入矩阵的格子,所以如果矩阵上的点是对应的字符,需要把对应的元素标记为已访问。

代码

C++

class Solution {
public:
 vector<vector<int>> direction ={{0,1},{0,-1},{1,0},{-1,0}}; # 四个方向
    bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0) return false;
        if(board[0].size()==0) return false;
        int wordIndex = 0;									 # wordIndex表示word中已经找到的下标
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board[0].size();j++){
                if(board[i][j]==word[wordIndex]){			 # 遍历找到word的开始字符
                    board[i][j]='1';					     # 设为1 表示已经访问过该节点
                    if(ifExist(board,word,wordIndex+1,i,j))  # 回溯判断是否存在路径
                        return true;
                    board[i][j]=word[wordIndex];             # 没找到路径 需要回溯 标记重新设为原始值
                }
            }
        }
        return false;
    }
    bool ifExist(vector<vector<char>>& board, string word, int wordIndex,int i,int j){
        if(wordIndex==word.size()) return true;             # 终止条件 所有字符都已经找到
        for(vector<int> dir:direction){						# 遍历4个方向
            int iNext = i + dir[0];							# 获取对应的x轴和y轴
            int jNext = j + dir[1];
            if(iNext<0 || iNext>=board.size()||jNext<0||jNext>=board[0].size()||board[iNext][jNext]=='1'||board[iNext][jNext]!=word[wordIndex])				
                continue;   # 前四个是矩形边界 第5个是该节点已经访问过 第6个是该节点不是对应的字符 
            board[iNext][jNext]='1';		# 否则该节点是对应的字符 标记已经访问过
            if(ifExist(board,word,wordIndex+1,iNext,jNext))   # 对该节点递归调用 
                return true;
            board[iNext][jNext]=word[wordIndex];  # 否则修改标记为原来的字符
        }
        return false;  
    }  
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值