题目描述:给定一个二维网格和一个单词,找出该单词是否存在于网格中。

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

例子:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
1
2
3
4
5
6
7
8
9
10

# 解法:深度优先遍历 + 回溯

准备两个函数exist()__exist()

exist() 用于循环遍历网格,当前元素等于单词的第一个字母时,进入 __exist() 函数。代码实现如下:

// ac地址:https://leetcode-cn.com/problems/word-search/
// 原文地址:https://xxoo521.com/2020-02-17-word-search/

/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function (board, word) {
    const rowNum = board.length;
    const colNum = board[0].length;

    for (let i = 0; i < rowNum; ++i) {
        for (let j = 0; j < colNum; ++j) {
            if (board[i][j] === word[0]) {
                const isExist = __exist(board, word, i, j, {});
                if (isExist) return true; // 找到就返回
            }
        }
    }
    return false;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

__exist() 函数是从指定位置开始,按照“上下左右”四个方向递归遍历,直到找到/找不到所有匹配的字母为止。代码实现如下:

/**
 * @param {character[][]} board
 * @param {string} word
 * @param {number} row
 * @param {number} col
 * @param {object} visited
 * @return {boolean}
 */
function __exist(board, word, row, col, visited) {
    // 单词中字母全部匹配,说明可以搜索到,返回true
    if (!word.length) {
        return true;
    }

    const key = `${row}-${col}`;
    // 越界、之前访问过、单词首字母和当前元素不相同,返回false
    if (
        row >= board.length ||
        row < 0 ||
        col >= board[0].length ||
        col < 0 ||
        visited[key] ||
        board[row][col] !== word[0]
    ) {
        return false;
    }

    visited[key] = true;
    word = word.slice(1);
    // 下、上、右、左搜索(顺序不重要)
    const success =
        __exist(board, word, row + 1, col, visited) ||
        __exist(board, word, row - 1, col, visited) ||
        __exist(board, word, row, col + 1, visited) ||
        __exist(board, word, row, col - 1, visited);

    // success为false时,就是回溯
    visited[key] = success;
    return success;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

代码中如果 success 为 false,说明以当前元素为出发点,搜索剩余字母失败。那么应该将visited[key]重置为 false,以方面其他路径使用。

例如对于以下数组,要搜索abbcbd。按照代码里的方向搜索逻辑,会先找到 abbd,然后发现查找失败,此时就要回溯。否则当按照正确方向找来时,visited 中的值是错误的。

a b b
d b c
1
2

# 更多资料

来自: LeetCode 79.单词搜索 - JavaScript | 心谭博客
作者:心谭
Star仓库:github