【算法-剑指 Offer】12. 矩阵中的路径(回溯)

剑指 Offer 12. 矩阵中的路径 - 力扣(LeetCode)

文章起笔:2021年11月16日16:53:53

问题描述及示例

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

例如,在下面的 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

提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 仅由大小写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解

严格来说不是我的题解,因为关键的递归逻辑没有处理好,始终无法得到正确答案,所以就直接去看了题解区的解析。

感谢题友【@Krahets】的分享:
参考:面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解) - 矩阵中的路径 - 力扣(LeetCode)

以上面提到的题解为参照,我在自己原先写的基础上做了点修改,大致就是对上面代码的翻译罢了。所以此处就不再赘述过程了。上面的题解中有详细的描述。另外本题也和LeetCode官方的另一道题目是一样的,这在本题的描述区有提示,那道题的题解区也有相关的题解描述,也可以作为参照。

/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function(board, word) {
  for(let i = 0; i < board.length; i++) {
    for(let j = 0; j < board[0].length; j++) {
      if(isMathch(i, j, 0)) {
        return true;
      }
    }
  }
  return false;

  // isMatch 函数是一个递归函数,用于确定以 board[x][y] 为起点是否可以
  // 找到与 word[charIndex] ~ word[word.length-1] 匹配的路径,其返回值为布尔值
  function isMathch(x, y, charIndex) {
    // 前四个条件用于判断当前坐标是否已经越界,最后一个条件用于判断当前遍历的字符是否
    // 可以与word中的下一个字符相匹配,这其中任意一个条件满足都可以直接返回false
    if(x < 0 || y < 0 || x >= board.length || y >= board[0].length || board[x][y] !== word[charIndex]) {
      return false;
    }
    // 如果当前遍历字符与word中的下一个字符相匹配,且该字符恰好是word中的最后一个字符
    // 则说明在board中找到了一条符合条件的路径,由于我们只需要判断存在性,
    // 所以此时可以直接返回true
    if(charIndex === word.length - 1) {
      return true;
    }
    // 如果当前的路径还没有匹配完,则要继续往下递归探索,在此之前,为了标志当前坐标已经被遍历过了,此时,应当给当前遍历字符置为一个特殊的字符,只要保证word中没有该字符即可
    board[x][y] = '#';
    // 完成标志操作后就应当继续往下探索,注意下面是用或运算符连接四个方向上的递归探索
    // 只要其中任意一个方向可以匹配,就会以此为基础继续往下探索,
    // 同时也不要忘了用一个变量接受探索的结果
    let result =  isMathch(x - 1, y, charIndex + 1) || isMathch(x, y + 1, charIndex + 1) || isMathch(x + 1, y, charIndex + 1) || isMathch(x, y - 1, charIndex + 1);
    // 上面在四个方向都尝试探索了一遍之后,就应当将当前遍历的这个字符恢复为原来的样子
    // 这也是回溯的关键操作!
    board[x][y] = word[charIndex];
    // 最后返回整个回溯过程的结果
    return result;
  }
};


提交记录
执行结果:通过
执行用时:100 ms, 在所有 JavaScript 提交中击败了43.67%的用户
内存消耗:40.4 MB, 在所有 JavaScript 提交中击败了97.55%的用户
通过测试用例:87 / 87
时间:2021/11/16 17:00	

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

【更新结束】

更新:2021年11月16日16:59:11

参考:面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解) - 矩阵中的路径 - 力扣(LeetCode)

注意:以上为题解区的精选题解。

【更新结束】

有关参考

更新:2021年11月16日16:59:11
参考:面试题12. 矩阵中的路径( DFS + 剪枝 ,清晰图解) - 矩阵中的路径 - 力扣(LeetCode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值