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)
相关推荐
UP_Continue33 分钟前
排序--计数排序
数据结构·算法
牵手夏日3 小时前
题目类型——左右逢源
算法
愚润求学4 小时前
【递归、搜索与回溯】FloodFill算法(一)
c++·算法·leetcode
sunny-ll6 小时前
【C++】详解vector二维数组的全部操作(超细图例解析!!!)
c语言·开发语言·c++·算法·面试
嵌入式@秋刀鱼7 小时前
《第四章-筋骨淬炼》 C++修炼生涯笔记(基础篇)数组与函数
开发语言·数据结构·c++·笔记·算法·链表·visual studio code
嵌入式@秋刀鱼7 小时前
《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
c语言·开发语言·数据结构·c++·笔记·算法·visual studio code
简简单单做算法7 小时前
基于PSO粒子群优化的VMD-LSTM时间序列预测算法matlab仿真
算法·matlab·lstm·时间序列预测·pso·vmd-lstm·pso-vmd-lstm
无聊的小坏坏7 小时前
高精度算法详解:从原理到加减乘除的完整实现
算法
愚润求学7 小时前
【递归、搜索与回溯】FloodFill算法(二)
c++·算法·leetcode
泽02027 小时前
C++之list的自我实现
开发语言·数据结构·c++·算法·list