LeetCode 热题 HOT — 单词搜索

132 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 20 天,点击查看活动详情

单词搜索

原题地址

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

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

示例 1:

image.png

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • boardword 仅由大小写英文字母组成

思路分析

  1. 分析题目,需要从上到下、从左到右遍历网格,判断在网格的坐标上是否可以搜索到单词 word 中的字符;
  2. 定义一个 visited 数组,来标记网格中的每个坐标是否有被访问过;
  3. 如果网格上的坐标上的字符跟字符串所在位置的字符不相等,则说明这条路径搜索失败,返回 false;若搜索到了,则证明找到了网格中的一条路径;
  4. 然后再顺着当前网格的坐标的上下左右四个方向继续搜索,若没有找到单词中的子串,则进行回溯,重新搜索;
  5. 最后遍历数组,每个位置执行单词中每个字符的搜索,返回对应的结果。

AC 代码

/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function(board, word) {
    const height = board.length
    const width = board[0].length
    const visited = new Array(height).fill(false).map(() => new Array(width).fill(false))

    const check = (i, j, s, k) => {
        if (board[i][j] != s.charAt(k)) {
            return false
        } else if (k == s.length - 1) {
            return true
        }
        visited[i][j] = true
        let result = false
        
        // 向右寻找
        if (i >= 0 && i < height && j + 1 >= 0 && j + 1 < width) {
            if (!visited[i][j + 1]) {
                const flag = check(i, j + 1, s, k + 1)
                if (flag) {
                    result = true
                }
            }
        }

        // 向左寻找
        if (i >= 0 && i < height && j - 1 >= 0 && j - 1 < width) {
            if (!visited[i][j - 1]) {
                const flag = check(i, j - 1, s, k + 1)
                if (flag) {
                    result = true
                }
            }
        }

        // 向下寻找
        if (i + 1 >= 0 && i + 1 < height && j >= 0 && j < width) {
            if (!visited[i + 1][j]) {
                const flag = check(i + 1, j, s, k + 1)
                if (flag) {
                    result = true
                }
            }
        }

        // 向上寻找
        if (i - 1 >= 0 && i - 1 < height && j >= 0 && j < width) {
            if (!visited[i - 1][j]) {
                const flag = check(i - 1, j, s, k + 1)
                if (flag) {
                    result = true
                }
            }
        }

        visited[i][j] = false
        return result
    }

    for (let i = 0; i < height; i++) {
        for (let j = 0; j < width; j++) {
            const flag = check(i, j, word, 0)
            if (flag) {
                return true
            }
        }
    }
    return false
};

结果:

  • 执行结果: 通过
  • 执行用时:284 ms, 在所有 JavaScript 提交中击败了91.91%的用户
  • 内存消耗:42.3 MB, 在所有 JavaScript 提交中击败了31.72%的用户
  • 通过测试用例:83 / 83

END