Word Search II in Python

The Word Search II problem involves finding all words from a dictionary that can be formed in a 2D character board. Each word must be constructed from letters of sequentially adjacent cells (horizontally or vertically neighboring), and the same letter cell cannot be used more than once in a single word.

This problem is efficiently solved using a Trie (prefix tree) data structure combined with backtracking. The Trie allows us to prune search paths early when no dictionary word has the current prefix.

Algorithm Overview

The solution follows these key steps ?

  • Build a Trie from all dictionary words

  • For each cell in the board, start a DFS search

  • Use backtracking to explore all possible paths

  • Mark visited cells temporarily to avoid reuse

  • When a complete word is found, add it to results

Example

Let's implement the complete solution ?

class Solution:
    def findWords(self, board, words):
        self.result = []
        trie = {}
        
        # Build Trie from dictionary words
        for word in words:
            self.insert_word(word, trie)
        
        # Search for words starting from each cell
        for i in range(len(board)):
            for j in range(len(board[0])):
                self.search(board, trie, i, j, "")
        
        return self.result
    
    def insert_word(self, word, trie):
        """Insert a word into the Trie"""
        current = trie
        for char in word:
            if char not in current:
                current[char] = {}
            current = current[char]
        current['#'] = True  # Mark end of word
    
    def search(self, board, trie_node, i, j, current_word=""):
        """DFS search with backtracking"""
        # Check bounds
        if i < 0 or j < 0 or i >= len(board) or j >= len(board[0]):
            return
        
        char = board[i][j]
        
        # Check if current character exists in Trie
        if char not in trie_node:
            return
        
        # Move to next Trie node and build word
        trie_node = trie_node[char]
        current_word += char
        
        # Check if we found a complete word
        if '#' in trie_node and trie_node['#']:
            self.result.append(current_word)
            trie_node['#'] = False  # Avoid duplicates
        
        # Mark cell as visited
        board[i][j] = '*'
        
        # Explore all 4 directions
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
        for di, dj in directions:
            self.search(board, trie_node, i + di, j + dj, current_word)
        
        # Restore cell (backtrack)
        board[i][j] = char

# Test the solution
solution = Solution()
board = [
    ["o", "a", "a", "n"],
    ["e", "t", "e", "a"], 
    ["i", "h", "k", "r"],
    ["i", "f", "l", "v"]
]
words = ["oath", "pea", "tea", "rain"]

result = solution.findWords(board, words)
print("Found words:", result)
Found words: ['oath', 'tea']

How It Works

The algorithm uses a Trie data structure to store all dictionary words efficiently. During the search phase ?

  1. Trie Construction: Each word is inserted character by character, with '#' marking word endings

  2. Board Traversal: Starting from each cell, we perform DFS

  3. Path Validation: We only continue if the current path exists in the Trie

  4. Backtracking: We mark cells as visited ('*') during search, then restore them

  5. Word Detection: When we reach a '#' marker, we've found a complete word

Time and Space Complexity

The solution has the following complexity ?

  • Time Complexity: O(M × N × 4^L) where M×N is board size and L is maximum word length

  • Space Complexity: O(K × L) for the Trie, where K is number of words

Key Optimizations

  • Early Pruning: Trie structure eliminates impossible paths early

  • Duplicate Prevention: Setting trie_node['#'] = False prevents duplicate results

  • Backtracking: Allows reusing cells for different words

Conclusion

Word Search II efficiently finds all dictionary words in a 2D board using Trie for prefix matching and backtracking for path exploration. The Trie structure provides significant optimization by pruning impossible search paths early.

Updated on: 2026-03-25T08:40:53+05:30

794 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements