【JS每日一算法】🟨73.单词搜索(递归回溯)

569 阅读2分钟

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

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

提示:

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

 示例:

word2.jpg

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

题解:

更多JS版本题解点击链接关注该仓库👀

/**
 * @description: 递归回溯   TC:O(2^n)  SC:O(n^2)
 * @author: JunLiangWang
 * @param {*} board  给定二维矩阵
 * @param {*} word   给定字符串单词
 * @return {*}
 */
function recursionBackTracking(board, word) {
    /**
     * 该方案使用递归回溯模拟选择word单词过程
     */
    
    // 矩阵高度
    let m = board.length,
    // 矩阵宽度
     n = board[0].length;
    // 如果矩阵字符数量小于单词字符数量,证明无法
    // 从矩阵中找到单词,直接返回false
    if (m * n < word.length) return false

    /**
     * @description: 递归
     * @author: JunLiangWang
     * @param {*} row   矩阵当前行索引
     * @param {*} col   矩阵当前列索引
     * @param {*} index 单词当前索引 
     * @param {*} list  在矩阵中已选中的单词列表(二维矩阵的一维映射)
     * @return {*}
     */    
    function recursion(row, col, index, list) {
        // 如果行/列索引超过范围,或矩阵当前元素不等于word当前元素,直接返回false
        if (row < 0 || col < 0 || row >= m || col >= n || board[row][col] != word[index]) return false;
        // 由于list是二维矩阵的一维映射,因此在二维矩阵元素在list的位置为:row*n+col;
        let cuIndex = row * n + col;
        // 如果当前索引等于word最后一个单词索引,证明已找到所有单词,直接返回true
        if (index == word.length - 1) return true;
        // 在list中记录矩阵该元素已被选中
        list[cuIndex] = true;

        // 如果下一个元素未被选中,使用下一个元素继续递归
        if (list[cuIndex + n] == false && recursion(row + 1, col, index + 1, [...list]))
            return true;
        // 如果上一个元素未被选中,使用上一个元素继续递归
        if (list[cuIndex - n] == false && recursion(row - 1, col, index + 1, [...list]))
            return true;
        // 如果右一个元素未被选中,使用右一个元素继续递归
        if (list[cuIndex + 1] == false && recursion(row, col + 1, index + 1, [...list]))
            return true;
        // 如果左一个元素未被选中,使用左一个元素继续递归
        if (list[cuIndex - 1] == false && recursion(row, col - 1, index + 1, [...list]))
            return true;
        // 所有递归仍无法满足,直接返回false
        return false;
    }

    // 遍历矩阵元素,从左到右/从上到下以其为开始点执行递归
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            // 如果递归结果为true,证明已找到所有元素,返回true
            if (recursion(i, j, 0, new Array(m * n).fill(false))) return true;
        }
    }
    // 遍历所有元素仍未满足,则返回false 
    return false;
}

来源:力扣(LeetCode)