Program to count number of words we can generate from matrix of letters in Python

Suppose we have a 4 x 4 board of letters and a list of words, we have to find the largest number of words that can be generated in the board by a sequence of adjacent letters, using one cell at most once per word (but we can reuse cells for other words). We can go up, down, left, right, or diagonal direction.

Problem Example

If the input is like ?

m b f d
x a y a
t z t r
s q q q

words = ["bat", "far", "mat"], then the output will be 3, as we can generate mat [0,1] ? [1,1] ? [2,0], bat [0,2] ? [1,1] ? [2,2], and far [0,2] ? [1,3] ? [2,3].

Algorithm Approach

To solve this, we will follow these steps ?

  • Build a trie (prefix tree) from all words for efficient word searching
  • Use depth-first search (DFS) with backtracking to explore all possible paths
  • Mark visited cells temporarily during each word search
  • Count words found and remove them from the trie to avoid duplicates

Implementation

class Solution:
    def solve(self, matrix, words):
        rows = len(matrix)
        cols = len(matrix[0])
        
        # Build trie from words
        trie = {}
        for word in words:
            current = trie
            for char in word:
                if char not in current:
                    current[char] = {}
                current = current[char]
            current["*"] = True  # Mark end of word
        
        found_count = 0
        
        def dfs(x, y, trie_node):
            nonlocal found_count
            
            # If we found a complete word
            if "*" in trie_node:
                del trie_node["*"]  # Remove to avoid counting again
                found_count += 1
            
            # Save current cell value and mark as visited
            temp = matrix[x][y]
            matrix[x][y] = "#"
            
            # Explore all 8 directions (including diagonals)
            for i in range(x-1, x+2):
                for j in range(y-1, y+2):
                    if (0 <= i < rows and 0 <= j < cols and 
                        matrix[i][j] != "#" and matrix[i][j] in trie_node):
                        dfs(i, j, trie_node[matrix[i][j]])
            
            # Restore cell value (backtrack)
            matrix[x][y] = temp
        
        # Try starting from each cell
        for i in range(rows):
            for j in range(cols):
                if matrix[i][j] in trie:
                    dfs(i, j, trie[matrix[i][j]])
        
        return found_count

# Test the solution
ob = Solution()
matrix = [
    ["m", "b", "f", "d"],
    ["x", "a", "y", "a"],
    ["t", "z", "t", "r"],
    ["s", "q", "q", "q"]
]
words = ["bat", "far", "mat"]
result = ob.solve(matrix, words)
print(f"Number of words found: {result}")

Output

Number of words found: 3

How It Works

The algorithm uses a trie data structure to efficiently store and search for words. Here's the process ?

  • Trie Construction: All words are inserted into a trie for fast prefix matching
  • DFS Search: For each cell, we explore all 8 adjacent directions recursively
  • Backtracking: Cells are temporarily marked as visited ("#") and restored after exploration
  • Word Detection: When we reach a trie node with "*", we've found a complete word

Key Points

  • Each cell can be used multiple times across different words
  • Within a single word search, each cell can only be used once
  • Movement is allowed in all 8 directions (horizontal, vertical, diagonal)
  • The trie prevents counting the same word multiple times

Conclusion

This solution combines trie data structure with DFS backtracking to efficiently find all possible words in a letter matrix. The approach ensures optimal word searching while preventing duplicate counting through trie manipulation.

Updated on: 2026-03-25T13:44:21+05:30

356 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements