Leetcode 79. 单词搜索 --javascript DFS

79. 单词搜索

描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。若是 word 存在于网格中,返回 true ;不然,返回 false 。javascript

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

image.png

image.png

image.png 提示:markdown

m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成
复制代码

题解

回溯法

回溯法(backtracking)是优先搜索的一种特殊状况,又称为试探法,经常使用于须要记录节点状态的深度优先搜索。一般来讲,排列、组合、选择类问题使用回溯法比较方便。 顾名思义,回溯法的核心是回溯。在搜索到某一节点的时候,若是咱们发现目前的节点(及其子节点)并非需求目标时,咱们回退到原来的节点继续搜索,而且把在目前节点修改的状态 还原。函数

这样的好处是咱们能够始终只对图的总状态进行修改,而非每次遍历时新建一个图来储存 状态。 在具体的写法上,它与普通的深度优先搜索同样,都有 [修改当前节点状态]→[递归子节 点] 的步骤,只是多了回溯的步骤,变成了 [修改当前节点状态]→[递归子节点]→[回改当前节点 状态]。 回溯法。有两个小诀窍,一是按引用传状态,二是全部的状态修 改在递归完成后回改。 回溯法修改通常有两种状况,一种是修改最后一位输出,好比排列组合;一种是修改访问标 记,好比矩阵里搜字符串。ui

解析

不一样于排列组合修改输出方式,而是修改访问标记。spa

在咱们对任意位置进行深度优先搜索时,咱们先标记当前位置为已访问,以免重复遍历(如防止向右搜索后 又向左返回);code

在全部的可能都搜索完成后,再回改当前位置为未访问,防止干扰其它位置搜索 到当前位置。orm

使用回溯法,咱们能够只对一个二维的访问矩阵进行修改,而不用把每次的搜索状 态做为一个新对象传入递归函数中。对象

coding

/** * @param {character[][]} board * @param {string} word * @return {boolean} */
const direction = [-1, 0, 1, 0, -1];
const exist = function(board, word) {
   if(!board.length) return false;
   let m = board.length, n = board[0].length;
   let visited = Array.from({length: m}, ()=> Array(n).fill(false));
   const find = {flag:false};
   for(let i = 0; i < m; i++) {
       for(let j = 0; j < n; j++) {
            backtracking(i, j, board, word, find, visited, 0);
       }
   }
   return find.flag;
};
const backtracking = function(i, j, board, word, find,visited, pos) {
    if(i < 0 || i >= board.length || j < 0 || j >= board[0].length) {
        return;
    } 
    if(visited[i][j] || (board[i][j] !== word[pos]) || find.flag) {
        return;
    }
    if(pos === word.length - 1) {
      find.flag = true
      return;
    }
    visited[i][j] = true; // 修改当前节点状态。
     for(let k = 0; k < 4; k++){
         const dx = i + direction[k];
         const dy = j + direction[k+1];
         backtracking(dx, dy, board, word,find, visited, pos + 1);
     }
     visited[i][j] = false; // 恢复节点状态;

}

复制代码
相关文章
相关标签/搜索