剑指 offer 搜索算法题:矩阵中的路径

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

分析:

        深度优先搜索法(回溯),典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝解决。深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为可行性剪枝。

  1. 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k;
  2. 超过行、列边界,或 当前遍历的字母不等于当前单词中的字母 或 当前字母已经访问过(后面两者可合并,在该路径开始之初,设置字母为空字符,回溯到当前节点时, 改回原来的字母);
  3.  朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS)。

求解

// 深度优先搜索法(dfs)
function exist(board: string[][], word: string): boolean {
  const row = board?.length;
  const col = board?.[0]?.length;
  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (dfs(board, i, j, word, 0)) {
        return true;
      }
    }
  }
  return false;
}

// 深度优先搜索
function dfs(board: string[][], i: number, j: number, word: string, index: number): boolean {
  // 超过行、列边界,或 当前遍历的字母不等于 当前单词中的字母
  if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] !== word[index]) return false;
  // board[i][j] === word[index]才会走到这里,
  // 遍历到单词末尾都相等
  if (index === word.length - 1) return true;
  // 标记当前节点访问过
  board[i][j] = '';
  // 向四个方向对比
  const res =
    dfs(board, i + 1, j, word, index + 1) ||
    dfs(board, i, j + 1, word, index + 1) ||
    dfs(board, i - 1, j, word, index + 1) ||
    dfs(board, i, j - 1, word, index + 1);
  // 回溯到当前节点时, 改回原来的字母
  // 以便从其他字母出发的能访问到该字母
  board[i][j] = word[index];
  return res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值