剑指offer11_矩阵中的路径

矩阵中的路径


请设计一个函数,用来判断在一个矩阵中是否存在一条路径包含的字符按访问顺序连在一起恰好为给定字符串。

路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。

如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。

注意:

  • 输入的路径字符串不为空;
  • 所有出现的字符均为大写英文字母;
数据范围

矩阵中元素的总个数 0,900。

路径字符串的总长度 1,900。

样例
c 复制代码
matrix=
[
  ["A","B","C","E"],
  ["S","F","C","S"],
  ["A","D","E","E"]
]

str="BCCE" , return "true" 

str="ASAE" , return "false"

题解

核心思想:深度优先搜索(DFS)结合回溯。

  1. 起点枚举 :
    遍历矩阵中的每一个单元格 (i, j) 作为可能的路径起点。
  2. DFS递归搜索 :
    从起点出发,依次匹配字符串的每个字符。具体步骤如下:
    • 终止条件 :
      当前字符与目标字符不匹配,或已匹配完所有字符(u == str.size() - 1)。
    • 路径探索 :
      向四个方向(上、右、下、左)扩展路径,并跳过越界或已访问的单元格。
    • 回溯恢复现场 :
      搜索结束后恢复当前单元格的原始字符,避免影响其他路径的搜索。
时间复杂度分析
  • 起点数量 :矩阵共有 m×n 个单元格,其中 m 为行数,n 为列数。
  • 路径分支 :
    每个字符匹配后,最多有 3 个新方向可选(不能走回头路),字符串长度为 k。
  • 总时间复杂度 :
    O(m×n×3ᵏ) ,其中 k 为字符串长度。
cpp 复制代码
class Solution {
public:
    bool hasPath(vector<vector<char>>& matrix, string str) {
        // 遍历所有可能的起点
        for (int i = 0; i < matrix.size(); i++) {
            for (int j = 0; j < matrix[i].size(); j++) {
                if (dfs(matrix, str, 0, i, j)) {
                    return true;
                }
            }
        }
        return false;
    }

    bool dfs(vector<vector<char>>& matrix, string& str, int u, int x, int y) {
        // 当前字符不匹配,直接返回false
        if (matrix[x][y] != str[u]) return false;
        // 已匹配所有字符,返回true
        if (u == str.size() - 1) return true;
        
        // 定义四个方向:上、右、下、左
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        // 保存当前字符并标记为已访问
        char original = matrix[x][y];
        matrix[x][y] = '*'; // 使用特殊字符标记已访问
        
        // 向四个方向递归搜索
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            // 检查新坐标是否越界
            if (nx >= 0 && nx < matrix.size() && ny >= 0 && ny < matrix[nx].size()) {
                if (dfs(matrix, str, u + 1, nx, ny)) {
                    return true; // 找到路径,提前返回
                }
            }
        }
        
        // 回溯:恢复当前单元格的原始字符
        matrix[x][y] = original;
        return false;
    }
};

代码解释
  1. 主函数 hasPath :
    • 遍历矩阵的每个单元格 (i, j),作为DFS的起点。
    • 若某一起点出发能找到完整路径,立即返回 true。
  2. 递归函数 dfs :
    • 参数说明 :
      • u:当前需匹配的字符在字符串中的索引。
      • x, y:当前搜索的矩阵坐标。
    • 字符匹配检查 :
      若当前单元格字符与目标字符不匹配,直接返回 false。
    • 终止条件 :
      若已匹配所有字符(u == str.size() - 1),返回 true。
    • 方向探索 :
      使用方向数组生成四个相邻坐标,过滤越界位置后递归搜索。
    • 回溯恢复现场 :
      将标记为 * 的单元格恢复为原字符,确保后续路径搜索不受影响。
关键细节
  • 避免重复访问 :
    通过临时修改当前单元格为特殊字符 *,确保同一路径中不重复使用单元格。
  • 剪枝优化 :
    一旦某条路径找到解,立即通过 return true 终止后续搜索,减少不必要的递归。
相关推荐
bnmoel4 小时前
C++ 基础入门篇(六)类和对象-第三篇:运算符重载
开发语言·c++·算法·语法·运算符重载
wuyk5554 小时前
28 搜索引擎索引更新:从 LSM Tree 到布隆过滤器的高效实现
stm32·单片机·嵌入式硬件·算法
小七在进步4 小时前
初识C++中的模板
java·开发语言·c++
我命由我123454 小时前
LRU 缓存淘汰策略
数据结构·redis·学习·mysql·算法·缓存·学习方法
垆边人似月.4 小时前
华为题:合并区间
数据结构·c++·算法
低频电磁之道4 小时前
C++ 中有符号与无符号类型混用可能导致的问题
开发语言·c++
垆边人似月.5 小时前
华为题:滑动窗口最大值
数据结构·c++·算法
2601_965742225 小时前
AI是怎么判断一家本地商家值得推荐的?云南老板看完这篇就懂了
大数据·人工智能·算法·ai·新媒体运营
小O的算法实验室5 小时前
IEEE TAES,基于DQN 辅助的集群无人机自组网约束多目标重构与优化
人工智能·算法
菩提树下的凡夫5 小时前
OPenCV4.8与OpenCV5.0的区别
c++·opencv