LeetCode 题解工作台

单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words , 返回所有二维网格上的单词 。 单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。 示例 1: 输入: …

category

5

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 回溯·pruning

bolt

答案摘要

我们首先将 `words` 中的单词构建成前缀树,前缀树的每个节点包含一个长度为 的数组 `children`,表示该节点的子节点,数组的下标表示子节点对应的字符,数组的值表示子节点的引用。同时,每个节点还包含一个整数 `ref`,表示该节点对应的单词在 `words` 中的引用,如果该节点不是单词的结尾,则 `ref` 的值为 。 接下来,我们对于 `board` 中的每个单元格,从该单元格出…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 回溯·pruning 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。

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

 

示例 1:

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]

示例 2:

输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]

 

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 12
  • board[i][j] 是一个小写英文字母
  • 1 <= words.length <= 3 * 104
  • 1 <= words[i].length <= 10
  • words[i] 由小写英文字母组成
  • words 中的所有字符串互不相同
lightbulb

解题思路

方法一:前缀树 + DFS

我们首先将 words 中的单词构建成前缀树,前缀树的每个节点包含一个长度为 2626 的数组 children,表示该节点的子节点,数组的下标表示子节点对应的字符,数组的值表示子节点的引用。同时,每个节点还包含一个整数 ref,表示该节点对应的单词在 words 中的引用,如果该节点不是单词的结尾,则 ref 的值为 1-1

接下来,我们对于 board 中的每个单元格,从该单元格出发,进行深度优先搜索,搜索过程中,如果当前单词不是前缀树中的单词,则剪枝,如果当前单词是前缀树中的单词,则将该单词加入答案,并将该单词在前缀树中的引用置为 1-1,表示该单词已经被找到,不需要再次搜索。

最后,我们将答案返回即可。

时间复杂度 (m×n×3l1)(m \times n \times 3^{l-1}),空间复杂度 (k×l)(k \times l)。其中 mmnn 分别是 board 的行数和列数。而 llkk 分别是 words 中的单词的平均长度和单词的个数。

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
41
42
43
class Trie:
    def __init__(self):
        self.children: List[Trie | None] = [None] * 26
        self.ref: int = -1

    def insert(self, w: str, ref: int):
        node = self
        for c in w:
            idx = ord(c) - ord('a')
            if node.children[idx] is None:
                node.children[idx] = Trie()
            node = node.children[idx]
        node.ref = ref


class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        def dfs(node: Trie, i: int, j: int):
            idx = ord(board[i][j]) - ord('a')
            if node.children[idx] is None:
                return
            node = node.children[idx]
            if node.ref >= 0:
                ans.append(words[node.ref])
                node.ref = -1
            c = board[i][j]
            board[i][j] = '#'
            for a, b in pairwise((-1, 0, 1, 0, -1)):
                x, y = i + a, j + b
                if 0 <= x < m and 0 <= y < n and board[x][y] != '#':
                    dfs(node, x, y)
            board[i][j] = c

        tree = Trie()
        for i, w in enumerate(words):
            tree.insert(w, i)
        m, n = len(board), len(board[0])
        ans = []
        for i in range(m):
            for j in range(n):
                dfs(tree, i, j)
        return ans
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The ability to optimize backtracking demonstrates an understanding of pruning and efficient search techniques.

  • question_mark

    Effective use of the Trie structure is a key indicator of solving this problem efficiently.

  • question_mark

    Understanding how to cut off unnecessary searches is critical for handling large test cases.

warning

常见陷阱

外企场景
  • error

    Not pruning the search early enough, leading to excessive recursion and time complexity.

  • error

    Forgetting to mark visited cells, which can cause revisiting and incorrect word formation.

  • error

    Using a brute-force approach without considering optimizations for large inputs.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Word Search III with multiple boards and word lists.

  • arrow_right_alt

    Word Search II on an NxM grid with varying path constraints.

  • arrow_right_alt

    Multi-level Word Search where the words are split across different sections of the board.

help

常见问题

外企场景

单词搜索 II题解:回溯·pruning | LeetCode #212 困难