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)
相关推荐
chao1898448 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
沪漂阿龙8 小时前
AI大模型面试题:支持向量机是什么?间隔最大化、软间隔、核函数、LinearSVC 全面拆解
人工智能·算法·支持向量机
little~钰8 小时前
倍增算法和ST表
算法
知识领航员9 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪9 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
如何原谅奋力过但无声10 小时前
【灵神高频面试题合集06-08】反转链表、快慢指针(环形链表/重排链表)、前后指针(删除链表/链表去重)
数据结构·python·算法·leetcode·链表
平行侠10 小时前
037插入排序 - 整理扑克牌的算法
数据结构·算法
ECT-OS-JiuHuaShan11 小时前
彻底定理化:从量子纠缠到量子代谢
数据库·人工智能·学习·算法·生活·量子计算
爱喝雪碧的可乐11 小时前
2026 腾讯广告算法大赛优秀方案启示:行为条件化多模态自回归生成推荐摘要
算法·数据挖掘·回归·推荐系统·推荐算法