#212
Word Search II
HardArrayStringBacktrackingTrieMatrixTrieBacktracking
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n² * k * 4^k) | O(n * k * m * 4^m) |
| Space | O(k) | O(n) |
💡
Intuition
Time O(n * k * m * 4^m)Space O(n)
The optimal solution uses a Trie to store the words and a backtracking approach to search for them on the board. This significantly reduces the number of unnecessary searches by allowing early termination when a prefix is not found.
⚙️
Algorithm
3 steps- 1Step 1: Build a Trie from the list of words.
- 2Step 2: For each cell in the board, start a backtracking search if the cell matches the first character of any word in the Trie.
- 3Step 3: If a complete word is found during the search, add it to the result set.
solution.py39 lines
1# Full working Python code
2class TrieNode:
3 def __init__(self):
4 self.children = {}
5 self.is_end_of_word = False
6
7class Solution:
8 def findWords(self, board, words):
9 self.result = set()
10 self.trie = TrieNode()
11 for word in words:
12 self.insert(word)
13 for i in range(len(board)):
14 for j in range(len(board[0])):
15 self.backtrack(board, i, j, self.trie, '')
16 return list(self.result)
17
18 def insert(self, word):
19 node = self.trie
20 for char in word:
21 if char not in node.children:
22 node.children[char] = TrieNode()
23 node = node.children[char]
24 node.is_end_of_word = True
25
26 def backtrack(self, board, x, y, node, path):
27 if node.is_end_of_word:
28 self.result.add(path)
29 node.is_end_of_word = False # Prevent duplicates
30 if x < 0 or x >= len(board) or y < 0 or y >= len(board[0]) or board[x][y] == '#':
31 return
32 char = board[x][y]
33 if char not in node.children:
34 return
35 board[x][y] = '#' # Mark as visited
36 for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
37 self.backtrack(board, x + dx, y + dy, node.children[char], path + char)
38 board[x][y] = char # Restore the cell
39ℹ
Complexity note: The time complexity is reduced because we only explore valid paths that match prefixes in the Trie, avoiding unnecessary searches. The space complexity is mainly due to the Trie structure.
- 1Using a Trie allows for efficient prefix searching, which is crucial in this problem.
- 2Backtracking can be optimized by marking cells as visited and restoring them after exploring.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.