Find all strings formed from characters mapped to digits of a number in Python

When working with digit-to-character mappings, we often need to generate all possible string combinations from a given number. This is similar to how old mobile phone keypads worked, where each digit mapped to multiple letters.

Problem Understanding

Given a mapping where each digit (1-9) corresponds to a list of characters, we need to find all possible strings that can be formed from a number. The key constraint is that we must use the same character for every occurrence of a digit in the number.

1 ? ['A', 'B', 'C']
2 ? ['D', 'E', 'F']  
3 ? ['G', 'H', 'I']
4 ? ['J', 'K', 'L']
5 ? ['M', 'N', 'O']
6 ? ['P', 'Q', 'R']
7 ? ['S', 'T', 'U']
8 ? ['V', 'W', 'X']
9 ? ['Y', 'Z']

For example, if the input is [4,3,5], and we choose 'J' for digit 4, then every occurrence of 4 must use 'J'.

Using itertools.product() Method

The most straightforward approach uses Python's itertools.product() to generate all combinations ?

import itertools

def find_combinations_simple(digits, mapping):
    # Get character options for each digit
    char_options = [mapping[digit - 1] for digit in digits]
    
    # Generate all combinations
    combinations = []
    for combo in itertools.product(*char_options):
        combinations.append(''.join(combo))
    
    return combinations

# Define the mapping
mapping = [['A', 'B', 'C'],  # 1
           ['D', 'E', 'F'],  # 2
           ['G', 'H', 'I'],  # 3
           ['J', 'K', 'L'],  # 4
           ['M', 'N', 'O'],  # 5
           ['P', 'Q', 'R'],  # 6
           ['S', 'T', 'U'],  # 7
           ['V', 'W', 'X'],  # 8
           ['Y', 'Z']]       # 9

digits = [4, 3, 5]
result = find_combinations_simple(digits, mapping)
print(' '.join(result))
JGM JGN JGO JHM JHN JHO JIM JIN JIO KGM KGN KGO KHM KHN KHO KIM KIN KIO LGM LGN LGO LHM LHN LHO LIM LIN LIO

Handling Repeated Digits

When digits repeat in the input, we need to ensure the same character is used for all occurrences ?

def find_combinations_with_repeats(digits, mapping):
    # Find unique digits and their positions
    unique_digits = []
    digit_positions = {}
    
    for i, digit in enumerate(digits):
        if digit not in digit_positions:
            unique_digits.append(digit)
            digit_positions[digit] = []
        digit_positions[digit].append(i)
    
    # Get character options for unique digits only
    char_options = [mapping[digit - 1] for digit in unique_digits]
    
    combinations = []
    for combo in itertools.product(*char_options):
        # Build the result string
        result = [''] * len(digits)
        for i, digit in enumerate(unique_digits):
            char = combo[i]
            for pos in digit_positions[digit]:
                result[pos] = char
        combinations.append(''.join(result))
    
    return combinations

# Test with repeated digits
digits = [4, 3, 4, 5]  # 4 appears twice
result = find_combinations_with_repeats(digits, mapping)
print(f"Input: {digits}")
print(f"First few combinations: {' '.join(result[:6])}")
print(f"Total combinations: {len(result)}")
Input: [4, 3, 4, 5]
First few combinations: JGJM JGJN JGJO JHJM JHJN JHJO
Total combinations: 18

Recursive Approach

Here's a recursive solution that builds combinations step by step ?

def find_combinations_recursive(digits, mapping):
    def backtrack(index, current_string, char_map):
        if index == len(digits):
            return [current_string]
        
        digit = digits[index]
        combinations = []
        
        if digit in char_map:
            # Use the already chosen character for this digit
            char = char_map[digit]
            combinations.extend(backtrack(index + 1, current_string + char, char_map))
        else:
            # Try all possible characters for this digit
            for char in mapping[digit - 1]:
                new_char_map = char_map.copy()
                new_char_map[digit] = char
                combinations.extend(backtrack(index + 1, current_string + char, new_char_map))
        
        return combinations
    
    return backtrack(0, "", {})

# Test the recursive approach
digits = [2, 3, 2]  # 2 appears twice
result = find_combinations_recursive(digits, mapping)
print(f"Input: {digits}")
print(f"Combinations: {' '.join(result)}")
Input: [2, 3, 2]
Combinations: DGD DHD DID EGE EHE EIE FGF FHF FIF

Comparison

Method Best For Time Complexity Space Complexity
itertools.product() Simple cases, no repeated digits O(k^n) O(k^n)
Manual handling Repeated digits, custom logic O(k^u) O(k^u)
Recursive Educational, custom constraints O(k^u) O(k^u × n)

Where k = average characters per digit, n = number of digits, u = unique digits

Conclusion

Use itertools.product() for simple cases without repeated digits. For repeated digits, manually handle unique digit mapping to ensure consistency. The recursive approach provides more control but uses more memory due to call stack overhead.

Updated on: 2026-03-25T09:13:01+05:30

334 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements