You are given a string word
containing lowercase English letters.
Telephone keypads have keys mapped with distinct collections of lowercase English letters, which can be used to form words by pushing them. For example, the key 2
is mapped with ["a","b","c"]
, we need to push the key one time to type "a"
, two times to type "b"
, and three times to type "c"
.
It is allowed to remap the keys numbered 2
to 9
to distinct collections of letters. The keys can be remapped to any amount of letters, but each letter must be mapped to exactly one key. You need to find the minimum number of times the keys will be pushed to type the string word
.
Return the minimum number of pushes needed to type word
after remapping the keys.
For example:
word = "abcde"
, the output is 5. We can remap 'a' to key 2 (1 push), 'b' to key 3 (1 push), 'c' to key 4 (1 push), 'd' to key 5 (1 push), and 'e' to key 6 (1 push). Total pushes = 5.word = "xyzxyzxyzxyz"
, the output is 12. We can remap 'x' to key 2 (1 push), 'y' to key 3 (1 push), and 'z' to key 4 (1 push). Since each letter appears 4 times, the total pushes = 4 + 4 + 4 = 12.word = "aabbccddeeffgghhiiiiii"
, the output is 24. An optimal mapping would be to map 'a' to key 2 (1 push), 'b' to key 3 (1 push), 'c' to key 4 (1 push), 'd' to key 5 (1 push), 'e' to key 6 (1 push), 'f' to key 7 (1 push), 'g' to key 8 (1 push), 'h' to key 9 (2 pushes), and 'i' to key 9 (1 push). Thus the pushes can be calculated as 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 2 * 2 + 6 * 1 = 24.What is the most efficient algorithm to solve this problem?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force approach for this typing problem is like trying out every possible keyboard layout and sequence of pushes. We essentially simulate typing the given word on every possible arrangement of letters on the keypad. We then count the number of pushes needed for each arrangement and find the minimum.
Here's how the algorithm would work step-by-step:
import itertools
def minimum_number_of_pushes_brute_force(word):
# Initialize minimum pushes to a large value
minimum_pushes = float('inf')
letters = sorted(list(set(word)))
# Iterate through all possible letter assignments
for permutation in itertools.permutations(letters):
letter_assignment = dict(zip(range(26), permutation))
total_pushes = 0
# Calculate pushes for current assignment
for char in word:
for key_number in range(26):
if letter_assignment[key_number] == char:
# Determine number of pushes based on the key
pushes = (key_number // 8) + 1
total_pushes += pushes
break
# Update minimum pushes if needed
minimum_pushes = min(minimum_pushes, total_pushes)
return minimum_pushes
The core idea is to figure out how frequently each letter appears and then strategically assign the most frequent letters to the easiest-to-reach keys on a phone's keypad. This minimizes the total number of key presses needed to type the word. We focus on the most commonly used letters first.
Here's how the algorithm would work step-by-step:
def calculate_minimum_pushes(word):
letter_frequencies = {}
for letter in word:
letter_frequencies[letter] = letter_frequencies.get(letter, 0) + 1
# Sort letters by frequency, most frequent first.
sorted_letter_frequencies = sorted(letter_frequencies.items(), key=lambda item: item[1], reverse=True)
keypad_presses = 0
press_count = 1
letter_index = 0
#Assign higher frequencies to lower press counts
for letter, frequency in sorted_letter_frequencies:
keypad_presses += frequency * press_count
letter_index += 1
if letter_index % 9 == 0:
press_count += 1
return keypad_presses
Case | How to Handle |
---|---|
Empty word list | Return 0 as no pushes are needed for an empty word list. |
Null or empty input word | Treat null/empty word as requiring 0 pushes or throw an IllegalArgumentException, depending on desired behavior. |
Word contains non-alphabetic characters | Filter out or reject words with non-alphabetic characters, or map them to a default key press sequence. |
All words are identical | The frequency counting should still accurately reflect the character distribution, so the algorithm works correctly. |
Very long words | The algorithm's time complexity is determined by the word length, so very long words will increase execution time. |
Maximum-sized input word list (e.g., many words of considerable length) | Ensure the data structures used (e.g., frequency map) are appropriately sized to prevent memory issues and optimize lookup. |
Word contains repeated characters consecutively, like 'AAA' | Character frequency is calculated correctly, handling repetitions without issue. |
Words with characters that need more than one push on a key (e.g., 's' requires 3 pushes) | Ensure the push count is correctly calculated based on the character's position on the phone keypad for each key. |