# Letter Combinations of a Phone Number

A comprehensive C++ solution for the classic "Letter Combinations of a Phone Number" problem.

## Problem Description

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent based on the traditional phone keypad mapping.

### Phone Keypad Mapping
```
2: abc    3: def    4: ghi
5: jkl    6: mno    7: pqrs
8: tuv    9: wxyz
```

### Examples
- Input: `"23"` → Output: `["ad","ae","af","bd","be","bf","cd","ce","cf"]`
- Input: `"2"` → Output: `["a","b","c"]`
- Input: `""` → Output: `[]`

## Solution Features

### Two Implementation Approaches
1. **Recursive Backtracking**: Uses depth-first search with backtracking
2. **Iterative Queue-based**: Builds combinations level by level

### Key Characteristics
- **Time Complexity**: O(3^N × 4^M) where N is digits with 3 letters, M is digits with 4 letters
- **Space Complexity**: O(3^N × 4^M) for storing all combinations
- **Input Validation**: Handles invalid digits (0, 1) and empty strings
- **Memory Efficient**: Uses reference parameters to avoid unnecessary copying

## File Structure

```
LetterCombinations.h              # Header file with class definition
LetterCombinations.cc             # Main implementation
test_letter_combinations.cc       # Comprehensive test suite
Makefile_letter_combinations      # Build configuration
README_LetterCombinations.md      # This documentation
```

## Class Design

### LetterCombinations Class
```cpp
class LetterCombinations {
public:
    // Main methods
    std::vector<std::string> GetCombinations(const std::string& digits);
    std::vector<std::string> GetCombinationsIterative(const std::string& digits);
    
    // Utility methods
    std::string GetLettersForDigit(int digit) const;
    void PrintCombinations(const std::vector<std::string>& combinations) const;
    void RunDemo();

private:
    // Internal methods
    void GenerateCombinationsRecursive(...);
    bool IsValidInput(const std::string& digits) const;
    
    // Data members
    std::unordered_map<int, std::string> mDigitMap;
};
```

## Building and Running

### Compilation
```bash
# Using the provided Makefile
make -f Makefile_letter_combinations

# Or compile manually
g++ -std=c++17 -Wall -Wextra -O2 -o letter_combinations LetterCombinations.cc
```

### Running the Program
```bash
# Run demo with predefined test cases
./letter_combinations

# The program includes an interactive mode for custom input
```

### Running Tests
```bash
# Compile and run test suite
g++ -std=c++17 -Wall -Wextra -O2 -o test_letter_combinations test_letter_combinations.cc LetterCombinations.cc
./test_letter_combinations
```

## Algorithm Details

### Recursive Approach
1. **Base Case**: When all digits are processed, add current combination to results
2. **Recursive Case**: For each letter of current digit, add to combination and recurse
3. **Backtracking**: Remove last character after recursive call returns

```cpp
void GenerateCombinationsRecursive(const std::string& digits, 
                                  int digit_index,
                                  std::string& current_combination,
                                  std::vector<std::string>& result) {
    if (digit_index == digits.length()) {
        result.push_back(current_combination);
        return;
    }
    
    int current_digit = digits[digit_index] - '0';
    const std::string& letters = mDigitMap[current_digit];
    
    for (char letter : letters) {
        current_combination.push_back(letter);
        GenerateCombinationsRecursive(digits, digit_index + 1, current_combination, result);
        current_combination.pop_back(); // backtrack
    }
}
```

### Iterative Approach
1. **Initialize**: Start with empty string in result vector
2. **Process Each Digit**: For each existing combination, create new combinations by appending each possible letter
3. **Update Results**: Replace result vector with new combinations

## Test Coverage

The test suite includes:
- **Empty Input**: Handles empty strings correctly
- **Single Digits**: Tests all valid digits (2-9)
- **Multiple Digits**: Tests combinations of 2, 3, and 4 digits
- **Invalid Input**: Properly handles digits 0 and 1
- **Edge Cases**: Tests digits with 4 letters (7, 9) and long inputs
- **Algorithm Consistency**: Verifies both recursive and iterative solutions produce identical results
- **Performance**: Tests with longer inputs to verify scalability

## Performance Analysis

### Complexity Analysis
- **Best Case**: Single digit → O(3) or O(4)
- **Average Case**: N digits → O(3^N) to O(4^N)
- **Worst Case**: All digits are 7 or 9 → O(4^N)

### Memory Usage
- **Input Storage**: O(N) for digit string
- **Output Storage**: O(3^N × 4^M × average_string_length)
- **Recursion Stack**: O(N) maximum depth

### Scalability
- Handles inputs up to reasonable length (tested with 8 digits = 7,776 combinations)
- Memory usage grows exponentially with input length
- Suitable for typical phone number lengths

## Code Quality Features

### Following C++ Best Practices
- **RAII**: Proper resource management
- **Const Correctness**: Methods marked const where appropriate
- **Reference Parameters**: Avoid unnecessary copying
- **STL Usage**: Leverages standard library containers and algorithms
- **Exception Safety**: Input validation prevents undefined behavior

### Style Compliance
- Follows established C++ naming conventions
- Clear separation of public/private interfaces
- Comprehensive documentation
- Consistent formatting and indentation

## Usage Examples

### Basic Usage
```cpp
LetterCombinations solution;
auto combinations = solution.GetCombinations("23");
solution.PrintCombinations(combinations);
// Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
```

### Comparing Algorithms
```cpp
LetterCombinations solution;
auto recursive_result = solution.GetCombinations("234");
auto iterative_result = solution.GetCombinationsIterative("234");
// Both produce identical results
```

### Interactive Demo
```cpp
LetterCombinations solution;
solution.RunDemo(); // Runs predefined test cases and interactive mode
```

## License

This project is licensed under the Apache License 2.0. See the license headers in source files for details.