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)
相关推荐
淡海水14 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
leobertlan14 小时前
好玩系列:训练一个神经网络模型指导小孩玩游戏2-大局观教练
算法
Tisfy15 小时前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯
乐迪信息15 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
木井巳17 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
心抵鹊17 小时前
归并排序之翻转对(hard)
数据结构·算法
白山编程大哥18 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
shehuiyuelaiyuehao18 小时前
算法34,位运算符操作,总结
算法
Navigator_Z18 小时前
LeetCode //C - 1224. Maximum Equal Frequency
c语言·算法·leetcode
Navigator_Z19 小时前
LeetCode //C++ - 1226. The Dining Philosophers
c语言·算法·leetcode