剑指Offer12.矩阵中的路径 C++

这篇具有很好参考价值的文章主要介绍了剑指Offer12.矩阵中的路径 C++。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、题目描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
剑指Offer12.矩阵中的路径 C++,剑指Offer刷题,矩阵,c++,力扣
示例 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

2、VS2019上运行

使用回溯的方法

#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
        // 检查当前坐标的字母是否与目标单词中的对应字母相等
        if (board[i][j] != s[k]) {
            return false;
        }
        // 如果已经匹配到目标单词的最后一个字母,表示找到了路径,返回true
        else if (k == s.length() - 1) {
            return true;
        }

        visited[i][j] = true; // 将当前坐标标记为已访问
        vector<pair<int, int>> directions{ {0, 1}, {0, -1}, {1, 0}, {-1, 0} }; // 上、下、左、右四个方向

        bool result = false; // 用于记录是否找到路径

        // 依次遍历四个方向
        for (const auto& dir : directions) {
            int newi = i + dir.first, newj = j + dir.second; // 计算新坐标
            // 检查新的坐标是否在矩阵范围内且没有被访问过
            if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) {
                if (!visited[newi][newj]) {//用于检查位置(newi, newj)是否已经被访问过
                    // 递归调用check函数进行下一步的搜索
                    bool flag = check(board, visited, newi, newj, s, k + 1);
                    if (flag) {
                        result = true; // 如果找到路径,直接返回true
                        break;
                    }
                }
            }
        }

        visited[i][j] = false; // 撤销对当前坐标的标记
        return result;
    }

    bool exist(vector<vector<char>>& board, string word) {
        int h = board.size(), w = board[0].size(); // 矩阵的行数和列数
        vector<vector<int>> visited(h, vector<int>(w)); // 记录每个格子的访问状态

        // 遍历矩阵的每个格子,对每个格子调用check函数
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                bool flag = check(board, visited, i, j, word, 0); // 调用check函数进行搜索
                if (flag) {
                    return true; // 如果找到路径,直接返回true
                }
            }
        }

        return false; // 遍历结束后仍未找到路径,返回false
    }
};

int main() {
    // 示例用法
    vector<vector<char>> board = {
        {'A', 'B', 'C', 'E'},
        {'S', 'F', 'C', 'S'},
        {'A', 'D', 'E', 'E'}
    };

    Solution s;
    string word = "ABCCED";

    if (s.exist(board, word)) {
        cout << "Word exists in the board." << endl;
    }
    else {
        cout << "Word does not exist in the board." << endl;
    }

    return 0;
}

Word exists in the board.

3、整体思路

整体的思路是使用深度优先搜索(DFS)算法在矩阵中搜索是否存在与目标单词匹配的路径。文章来源地址https://www.toymoban.com/news/detail-634094.html

  • 首先,定义一个 check 函数来进行递归的搜索。该函数接收当前的坐标 (i, j)、目标单词 s、以及目前匹配的字符索引 k。函数的返回值是一个布尔值,表示是否找到了匹配的路径。
  • 在 check 函数中,首先进行边界条件的判断。如果当前索引 k 已经匹配到目标单词的最后一个字符,说明已经找到了匹配的路径,返回 true。
  • 接下来,检查当前坐标 (i, j) 处的字母是否与目标单词中的对应字母相等。如果不相等,说明当前路径匹配失败,返回 false。
  • 检查新坐标是否在矩阵的范围内,并且该位置没有被访问过(即 visited[newi][newj] = false)。
    如果满足上述条件,则递归调用 check 函数,在新坐标 (newi, newj) 上继续匹配下一个字符,即 k + 1。
  • 如果递归调用返回 true,表示在某个方向上找到了匹配的路径,直接返回 true。
    如果所有方向的递归调用都没有找到匹配的路径,则撤销对当前坐标 (i, j) 的标记,将 visited[i][j] 设置为 false,表示可以重新访问该位置。
  • 最后,如果所有方向都探索完毕,仍然没有找到匹配的路径,则返回 false,表示没有找到路径。
  • 接下来可以调用 check 函数,从矩阵的每个位置出发,判断是否存在与目标单词匹配的路径。如果返回 true,则说明存在这样的路径;如果返回 false,则说明不存在。
  • 这就是整体的思路,通过DFS算法搜索矩阵中的路径,并利用递归和回溯的思想进行搜索和撤销标记。

4、int h = board.size(), w = board[0].size();

  • 这行代码int h = board.size(), w = board[0].size();的作用是获取二维字符向量board的行数h和列数w。
  • 1.board.size()返回二维字符向量board的行数,即向量中包含的子向量个数。
    2.board[0].size()返回二维字符向量board中第一行子向量的列数,假设矩阵不为空。

5、vector<vector> visited(h, vector(w));

  • 这行代码vector<vector<int>> visited(h, vector<int>(w));创建了一个名为visited的二维整数向量,其大小与输入矩阵board的行数和列数相同。
  • 1.vector<int>(w)部分创建了一个大小为w的整数向量。
  • 2.vector<vector<int>> visited(h, vector<int>(w));使用上述创建的子向量为每一行创建了一个整数向量,从而形成了一个大小为h行、w列的二维整数向量visited。
  • 这样的二维向量visited可以用于跟踪和记录在处理board矩阵时已经访问过的位置或标记。

6、dir.first 和dir.second

  • dir.first表示dir这个pair(键值对)中的第一个元素,即表示方向的行坐标变化。在该上下左右的方向向量中,dir.first表示上下移动的行坐标的变化量。
  • 例如,如果dir是(-1, 0),那么dir.first就是-1,表示向上移动1行。同理,如果dir是(1, 0),那么dir.first就是1,表示向下移动1行。
  • 在搜索一个矩阵的周围方向时,dir.first的值用于计算新的行坐标。通过将当前位置的行坐标i与dir.first相加,可以得到新的行坐标,用于在矩阵中检查相邻位置是否符合要求。

7、visited[i][j] = false;

  • 这行代码为撤销对当前坐标(i, j)的访问标记,将其重新设置为false。
  • 标记的目的是为了跟踪遍历矩阵时已经访问过的位置,以避免重复访问。在代码中,visited向量用于标记位置是否已经被访问过。
  • 当程序进行完成对位置(i, j)的处理后,如果希望在后续的搜索或迭代中能够重新访问该位置,就需要撤销对该位置的访问标记,将visited[i][j]重新设置为false。
  • 撤销对当前坐标的标记允许在后续的遍历或搜索过程中重新考虑访问该位置,以发现其他可能的路径或结果。如果不撤销标记的话,可能会导致某些位置被错误地标记为已访问,从而错过了找到其他路径或结果的机会。因此,需要在适当的时候撤销对当前坐标的标记。

8、for (const auto& dir : directions)

  • for (const auto& dir : directions) 是一个范围-based的循环语句,用于遍历容器 directions 中的元素。
  • 在这个语句中,dir 是一个临时变量,它会依次取到 directions 中的每个元素值。关键字 auto 会自动推断 dir 的类型,使其与 directions 中的元素类型保持一致。const 修饰符表示 dir 是一个常量,即在循环体内不能对它进行修改。
  • 通过这个循环语句,可以依次遍历 directions 容器中的每个方向,执行相应的操作,如计算新坐标 (newi, newj),进行路径匹配等。这样可以依次尝试不同的方向,以搜索矩阵中是否存在与目标单词匹配的路径。

到了这里,关于剑指Offer12.矩阵中的路径 C++的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用 Go 剑指 Offer 12. 矩阵中的路径

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使

    2023年04月10日
    浏览(39)
  • 剑指 Offer 12. 矩阵中的路径(回溯 DFS)

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

    2024年02月12日
    浏览(34)
  • 用 Go 剑指 Offer 12. 矩阵中的路径 (DFS + 回溯)

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使

    2023年04月10日
    浏览(40)
  • (搜索) 剑指 Offer 12. 矩阵中的路径 ——【Leetcode每日一题】

    难度:中等 给定一个 m * n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许

    2024年02月12日
    浏览(42)
  • 剑指 Offer 12. 矩阵中的路径 / LeetCode 79. 单词搜索(深度优先搜索)

    链接:剑指 Offer 12. 矩阵中的路径;LeetCode 79. 单词搜索 难度:中等 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相

    2024年02月02日
    浏览(42)
  • 剑指offer12 矩阵中的路径 13 机器人的运动范围 34.二叉树中和为某一值得路径

    //写的有点问题,暂时想不到怎么改,先放着,通过用例71/83 卡住的是abcd 但是改了又有问题 无语 看了 答案 都写不对 在类成员里面定义了row和col 就不要重复定义了 不然不知道为什么就开始发疯 先贴出蠢货写出来的东西 审题也审不明白 机器人只能上下左右走 不能一行一行

    2024年02月15日
    浏览(38)
  • 剑指offer(C++)-JZ29:顺时针打印矩阵(算法-模拟)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 则依次打印出数字 数据范围: 0 = matrix.length = 100 0 = ma

    2024年02月10日
    浏览(43)
  • 《剑指 Offer》专项突破版 - 面试题 13 : 二维子矩阵的数字之和(C++ 实现)- 二维前缀和

    题目链接 :LCR 013. 二维区域和检索 - 矩阵不可变 - 力扣(LeetCode) 题目 : 输入一个二维矩阵,如何计算给定左上角坐标和右下角坐标的子矩阵的数字之和?对于同一个二维矩阵,计算子矩阵的数字之和的函数可能由于输入不同的坐标而反复调用多次。 例如,对于下图中的二

    2024年01月18日
    浏览(41)
  • 力扣 [344、541、剑指offer 05.、151、剑指offer58-ll]

    双指针:自己的 双指针,左指针指向开头,右指针指向末尾。 交换两个左右指针。 左右指针向中间移动。 时间复杂度:O(n); 空间复杂度:O(1); 实现代码: 分类讨论:自己的 分类讨论: 如果剩余字符少于k个,则将剩余字符全部反转。 如果剩余字符大于或等于k个,则反

    2024年02月15日
    浏览(38)
  • 《剑指offer》——刷题日记

    本期,给大家带来的是《剑指offer》几道题目的讲解。希望对大家有所帮助!!! 本文目录 (一)JZ36 二叉搜索树与双向链表 1、题意分析 2、思路讲解 3、代码演示 4、最终结果 (二)BM6 判断链表中是否有环 1、题意分析 2、思路讲解 3、代码演示 4、最终结果 (三)JZ23 链

    2023年04月21日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包