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)
相关推荐
大明者省9 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_79810 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander25810 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记11 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI11 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型12 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光12 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院13 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡14 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
杨石兴14 小时前
31、玩具MoM:用2x2矩阵串起全套流程
人工智能·算法·矩阵·电磁学