Word Search II

Problem

Given an m x n board of characters and a list of strings words, return all words on the board.

Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

Example 1:

复制代码
Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
Output: ["eat","oath"]

Example 2:

复制代码
Input: board = [["a","b"],["c","d"]], words = ["abcb"]
Output: []

Intuition

The task is to find all words on the board that are present in the given list of words. We can use a Trie data structure to efficiently check whether a sequence of letters on the board forms a valid word. The Trie is built from the list of words, and a depth-first search (DFS) is performed on the board to explore possible word formations.

Approach

TrieNode Class:

Implement a TrieNode class with attributes:

children: A dictionary mapping characters to child nodes.

iswords: A boolean indicating whether the current node represents the end of a word.

TrieNode Method:

Implement an addword method in the TrieNode class to insert a word into the Trie.

Solution Class:

Implement a Solution class with a findWords method.

Initialize an empty Trie (root) and add each word from the list of words to the Trie.

DFS Function:

Implement a DFS function (dfs) to explore possible word formations on the board.

The DFS function takes parameters (r, c, node, word), where (r, c) represents the current position on the board, node represents the current node in the Trie, and word represents the sequence of letters formed so far.

Explore adjacent cells horizontally and vertically, checking if the next letter in the sequence is a valid child of the current Trie node. If yes, continue the DFS.

If the current Trie node represents the end of a word, add the word to the result set (res).

Main Function:

Iterate over each cell on the board and start the DFS from that cell, considering it as the starting point of a word.

Return the list of words present in the result set.

Complexity

  • Time complexity:

Trie Construction: The time complexity of Trie construction is O(w * m), where w is the number of words and m is the average length of the words. Each word of length m is inserted into the Trie.

DFS on Board: The time complexity of DFS on the board is O(rows * cols * 4^m), where rows and cols are the dimensions of the board, and m is the maximum length of a word. In the worst case, we explore 4 directions (horizontal and vertical) at each cell.

  • Space complexity:

Trie Construction: The space complexity of Trie construction is O(w * m), where w is the number of words and m is the average length of the words. Each character of each word is stored in the Trie.

DFS on Board: The space complexity of DFS on the board is O(m), where m is the maximum length of a word. This is the maximum depth of the recursion stack during DFS. The visit set is used to keep track of visited cells on the board.

Code

复制代码
class TrieNode:
    def __init__(self):
        self.children = {}
        self.iswords = False

    def addword(self, words):
        cur = self
        
        for c in words:
            if c not in cur.children:
                cur.children[c] = TrieNode()
            cur = cur.children[c]
        cur.iswords = True
class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        root = TrieNode()

        for w in words:
            root.addword(w)
        
        rows, cols = len(board), len(board[0])
        res, visit = set(), set()

        def dfs(r, c, node, word):
            if(r < 0 or c < 0 or
               r == rows or c == cols or
               (r, c) in visit or board[r][c] not in node.children):
               return

            visit.add((r, c))
            node = node.children[board[r][c]]
            word += board[r][c]
            if node.iswords:
                res.add(word)

            dfs(r + 1, c, node, word)
            dfs(r - 1, c, node, word)
            dfs(r, c - 1, node, word)
            dfs(r, c + 1, node, word)
            visit.remove((r, c))
        
        for r in range(rows):
            for c in range(cols):
                dfs(r, c, root, '')

        return list(res)
相关推荐
向阳逐梦30 分钟前
PID控制算法理论学习基础——单级PID控制
人工智能·算法
2zcode33 分钟前
基于Matlab多特征融合的可视化指纹识别系统
人工智能·算法·matlab
Owen_Q1 小时前
Leetcode百题斩-二分搜索
算法·leetcode·职场和发展
矢志航天的阿洪1 小时前
蒙特卡洛树搜索方法实践
算法
UnderTheTime2 小时前
2025 XYD Summer Camp 7.10 筛法
算法
zstar-_2 小时前
Claude code在Windows上的配置流程
笔记·算法·leetcode
圆头猫爹2 小时前
第34次CCF-CSP认证第4题,货物调度
c++·算法·动态规划
秋说2 小时前
【PTA数据结构 | C语言版】出栈序列的合法性
c语言·数据结构·算法
用户40315986396632 小时前
多窗口事件分发系统
java·算法
用户40315986396632 小时前
ARP 缓存与报文转发模拟
java·算法