矩阵中的路径(深度优先遍历)

这篇博客介绍了一种使用深度优先搜索(DFS)算法在给定的二维字符网格中查找指定单词的方法。算法从网格的左上角开始遍历,当找到单词的第一个字母时,会尝试向四个方向进行递归搜索,直到找到所有字母或搜索失败。如果所有字母都匹配成功,返回true,否则返回false。在搜索过程中,为了避免回溯路径上的重复访问,会临时将已访问过的字母替换为空,搜索结束后恢复原状。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

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

 

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pel5L2c5pyI5oGv,size_20,color_FFFFFF,t_70,g_se,x_16

 

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"

输出:true

 

示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"

输出:false

 

解题思路:

可以用深度优先遍历,从第一个字母开始遍历二维数组,找到第一个单词字母,然后先往一个方向搜索到底,如果不对再返回上一个元素,换另一个方向搜索,和图的深度优先遍历类似,用递归实现。如果字母全部匹配成功就返回真,其他则返回假,字母匹配成功则把该位置变为空,防止重复访问,在四个方向重复此运算(用递归),返回之前把该位置的值恢复。

 

算法流程:

public:

1.把二维数组的行数赋给变量line,列数赋给变量row

2.从二维数组的左上角第一个元素开始遍历整个二维数组,如果dfs函数从该元素开始匹配单词word成功,则返回true

3.返回false

 

private:

1.声明行数line,和列数row

2.定义dfs函数,传入二维数组,单词,行数 i,列数 j,单词字母的索引 k

               如果 i 越界或 j 越界或单词字母不匹配

                       返回false

               如果匹配成功

                       返回true

               把此位置变为空

               定义布尔变量res=四个方向上的递归的或(只要有一个匹配成功就行)

               把该位置的值恢复

               返回res

 

代码:

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
    line=board.size();
    row=board[0].size();
    for(int i=0;i<line;i++) {
        for(int j=0;j<row;j++) {
            if(dfs(board,word,i,j,0))
                return true;
        }
    }
    return false;
    }
private:
    int line,row;
    bool dfs(vector<vector<char>>& board,string word,int i,int j,int k) {
        if(i>=line||i<0||j>=row||j<0||
            board[i][j]!=word[k])
            return false;
        if(k==word.size()-1)
            return true;
        board[i][j]='\0';
        bool res=
           dfs(board,word,i+1,j,k+1)|| 
           dfs(board,word,i-1,j,k+1)||
           dfs(board,word,i,j+1,k+1)||
           dfs(board,word,i,j-1,k+1);
        board[i][j]=word[k];
        return res;
    }

};

 

运行步骤:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pel5L2c5pyI5oGv,size_20,color_FFFFFF,t_70,g_se,x_16

 (只考虑正确路径)

i=0,j=0,k=0,word.size()-1=5

dfs(board,word ,0,0,0),board[0][0]='\0',

dfs(board,word ,0,1,1),board[0][1]='\0',

dfs(board,word ,0,2,2),board[0][2]='\0',

dfs(board,word ,1,2,3),board[1][2]='\0',

dfs(board,word ,2,2,4),board[2][2]='\0',

dfs(board,word ,2,1,5),board[2][1]='\0',

k=word.size()-1=5,返回true

dfs(board,word ,2,1,5),board[2][1]='D',

返回true

dfs(board,word ,2,2,4),board[2][2]='E',

返回true

dfs(board,word ,1,2,3),board[1][2]='C',

返回true

dfs(board,word ,0,2,2),board[0][2]='C',

返回true

dfs(board,word ,0,1,1),board[0][1]='B',

返回true

dfs(board,word ,0,0,0),board[0][0]='A',

返回true

if(true)

返回true

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值