每天一道leetcode:剑指 Offer 12. 矩阵中的路径(中等&DFS深度优先遍历)

今日份题目:

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

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

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

示例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

提示

  • m == board.length

  • n = board[i].length

  • 1 <= m, n <= 6

  • 1 <= word.length <= 15

  • boardword仅由大小写英文字母组成

题目思路

DFS深度优先遍历,重点在于一次次的dfs递归调用。由于不知道从哪个位置开始遍历,所以遍历矩阵中所有的位置,在与字符串第一个字母相同的点开始dfs遍历判断是否有满足条件的情况。

dfs的具体过程:递归结束条件,如果中间某个位置的字母与字符串当前的字母不同,就返回false,如果字符串遍历完了,说明存在字符串,返回true。剩下的情况,需要遍历四个方向查看有无满足条件的下个位置,如果所有都有,就返回true,否则返回false。

代码

cpp 复制代码
class Solution 
{
public:
    bool dfs(vector<vector<char>>& board,vector<vector<int>>& visited,int i,int j,string& s,int k) 
    {
        if(board[i][j]!=s[k]) return false;
        else if(k==s.length()-1) return true;//遍历完字符串s了,说明存在字符串s
        visited[i][j]=1;//标记当前位置为已到过
        vector<pair<int,int> > directions{{0,1},{0,-1},{1,0},{-1,0}};//标记四个方向
        bool result=false;
        for(const auto& dir:directions) //遍历四个方向
        {
            int ii=i+dir.first,jj=j+dir.second;//新的位置
            if(ii>=0&&ii<board.size()&&jj>=0&&jj<board[0].size()) 
            {
                if(!visited[ii][jj]) //当前位置还未到过
                {
                    bool res=dfs(board,visited,ii,jj,s,k+1);//继续遍历下一个位置
                    if(res) //为真,说明四个方向中找到正确的位置,返回真
                    {
                        result=true;
                        break;
                    }
                }
            }
        }
        visited[i][j]=0;//注意:标记为0,未遍历过,便于其他情况的遍历
        return result;
    }

    bool exist(vector<vector<char>>& board, string word) 
    {
        int n=board.size(),m=board[0].size();
        vector<vector<int>> visited(n,vector<int>(m));
        for(int i=0;i<n;i++) //遍历矩阵的行
        {
            for(int j=0;j<m;j++) //遍历矩阵的列
            {
                if(board[i][j]==word[0])
                {
                    bool flag=dfs(board,visited,i,j,word,0);
                	if(flag) return true;//以当前位置为起点可以找到字母
                }
            }
        }
        return false;
    }
};

提交结果

欢迎大家在评论区讨论,如有不懂的代码部分,欢迎在评论区留言!

相关推荐
跨境海王哥1 分钟前
Facebook矩阵引流:从防封机制拆解
线性代数·矩阵·facebook
视觉AI4 分钟前
一帧就能“训练”的目标跟踪算法:通俗理解 KCF 的训练机制
人工智能·算法·目标跟踪
西西弗Sisyphus27 分钟前
线性代数 - 二阶矩阵的行列式、向量叉积(Cross product)的模长与平行四边形面积的关系
线性代数·矩阵·行列式
2301_7951672034 分钟前
玩转Rust高级应用 如何理解 Rust 实现免疫数据竞争的关键是Send 和 Sync 这两个 trait
开发语言·算法·rust
Blossom.11834 分钟前
AI Agent记忆系统深度实现:从短期记忆到长期人格的演进
人工智能·python·深度学习·算法·决策树·机器学习·copilot
贩卖黄昏的熊36 分钟前
数据结构示例代码
数据结构
Q741_1471 小时前
C++ 面试高频考点 链表 迭代 递归 力扣 25. K 个一组翻转链表 每日一题 题解
c++·算法·链表·面试·递归·迭代
syker1 小时前
手搓UEFI.h
c++
_fairyland1 小时前
数据结构 力扣 练习
数据结构·考研·算法·leetcode
LIZhang20162 小时前
基于ffmpeg8.0录制mp4文件
开发语言·c++