60.单词搜索

45 阅读2分钟

题目链接

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

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

解法 回溯

思路

进入回溯的条件是要找到字母的开头,接下来朝4个方向去搜寻下一个字母,而下一个字母肯定是要用一个变量 index 来控制的,其他的参数就剩下遍历当前格子的行和列了。

终止条件就是行和列超出范围,当前格子与 word[index] 上的字符对不上,以及之前访问过这个(因为不能重复访问),就返回 false。如果当前 index 递归到 word 最后一个字符,那说明完整了搜索,返回 true 即可。

下面给出的是带 visited 数组的写法,也在注释里给出了不需要额外空间的写法。

代码

function exist(board: string[][], word: string): boolean {
    const visited = new Array(board.length).fill(0).map(() => new Array(board[0].length).fill(false));
    const dfs = (row, col, index) => {        
        // board[row][col] === "#"
        if (row < 0 || col < 0 || row >= board.length || col >= board[0].length || board[row][col] !== word.charAt(index) || visited[row][col]) return false;
        if (index === word.length - 1) return true;
        
        // const temp = board[row][col];
        // board[row][col] = "#"
        visited[row][col] = true;
        const res = dfs(row + 1, col, index + 1) ||
            dfs(row, col + 1, index + 1) ||
            dfs(row - 1, col, index + 1) ||
            dfs(row, col - 1, index + 1);
        visited[row][col] = false;
        // board[row][col] = temp;
        return res;
    };
    
    for (let i = 0; i < board.length; i++) {
        for (let j = 0; j < board[0].length; j++) {
            if (dfs(i, j, 0)) return true;
        }
    }
    return false;
};

时空复杂度

时间复杂度:O(m * n * L) ,L 是单词长度

空间复杂度:O(m * n + L),如果不用 visted 数组就是递归栈调用的深度 O(L)