You are given a string word containing distinct 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.
An example mapping of letters to keys on a telephone keypad is given below. Note that 1, *, #, and 0 do not map to any letters.
Example 1:
Input: word = "abcde" Output: 5 Explanation: The remapped keypad given in the image provides the minimum cost. "a" -> one push on key 2 "b" -> one push on key 3 "c" -> one push on key 4 "d" -> one push on key 5 "e" -> one push on key 6 Total cost is 1 + 1 + 1 + 1 + 1 = 5. It can be shown that no other mapping can provide a lower cost.
Example 2:
Input: word = "xycdefghij" Output: 12 Explanation: The remapped keypad given in the image provides the minimum cost. "x" -> one push on key 2 "y" -> two pushes on key 2 "c" -> one push on key 3 "d" -> two pushes on key 3 "e" -> one push on key 4 "f" -> one push on key 5 "g" -> one push on key 6 "h" -> one push on key 7 "i" -> one push on key 8 "j" -> one push on key 9 Total cost is 1 + 2 + 1 + 2 + 1 + 1 + 1 + 1 + 1 + 1 = 12. It can be shown that no other mapping can provide a lower cost.
Constraints:
1 <= word.length <= 26word consists of lowercase English letters.word are distinct.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 strategy for this problem involves trying every single combination of button pushes to create the target word. We'll methodically go through all possible sequences, no matter how inefficient, until we find the shortest one. Think of it as trying every possible password combination until you get the right one.
Here's how the algorithm would work step-by-step:
def min_pushes_brute_force(word):
shortest_sequence_length = float('inf')
keyboard = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"],
["j", "k", "l"], ["m", "n", "o"], ["p", "q", "r", "s"],
["t", "u", "v"], ["w", "x", "y", "z"]]
def generate_sequences(current_sequence, current_word):
nonlocal shortest_sequence_length
if len(current_word) > len(word):
return
if current_word == word:
shortest_sequence_length = min(shortest_sequence_length, len(current_sequence))
return
# Try adding each possible button push to the current sequence
for button_index in range(len(keyboard)):
for letter_index, letter in enumerate(keyboard[button_index]):
# We try all combinations, inefficiently
generate_sequences(current_sequence + [(button_index + 2, letter_index + 1)], current_word + letter)
generate_sequences([], "")
if shortest_sequence_length == float('inf'):
return -1
# Calculate total number of pushes based on the shortest sequence.
total_pushes = 0
for _, press_count in get_button_press_counts(find_shortest_sequence(word, keyboard)):
total_pushes += press_count * keyboard_press_count_multiplier(press_count)
return total_pushes
def get_button_press_counts(button_press_sequence):
button_counts = {}
for button in button_press_sequence:
if button in button_counts:
button_counts[button] += 1
else:
button_counts[button] = 1
return button_counts.items()
def keyboard_press_count_multiplier(keyboard_press_count):
return keyboard_press_count
def find_shortest_sequence(word, keyboard):
button_press_sequence = []
for char in word:
for button_index in range(len(keyboard)):
if char in keyboard[button_index]:
button_press_sequence.append(button_index + 2)
break
return button_press_sequenceThe key is to realize that some letters on the phone keypad are typed with one push, some with two, and some with three or four. We want to assign the most frequent letters to the keys that require fewer pushes to minimize the overall count. The general idea is to sort the letters based on how often they appear and then assign them to the keys that require the fewest presses.
Here's how the algorithm would work step-by-step:
def minimum_number_of_pushes(word):
letter_counts = {}
for letter in word:
letter_counts[letter] = letter_counts.get(letter, 0) + 1
# Sort letters by frequency in descending order.
sorted_letter_counts = sorted(letter_counts.items(), key=lambda item: item[1], reverse=True)
presses_needed = {}
total_pushes = 0
index = 0
for i in range(1, 5):
for j in range(9):
# Ensure index is within the bounds of the sorted letters.
if index < len(sorted_letter_counts):
letter = sorted_letter_counts[index][0]
presses_needed[letter] = i
index += 1
else:
break
else:
continue
break
# Calculate total pushes based on letter frequencies.
for letter in word:
total_pushes += presses_needed[letter]
return total_pushes| Case | How to Handle |
|---|---|
| Null or empty input string | Return 0, as no pushes are required for an empty word. |
| Input string with a single character | Return 1, as a single character always requires one push. |
| Input string containing characters outside the 'a' to 'z' range | Handle as an invalid input and either return an error code or throw an exception. |
| Input string with all the same characters (e.g., 'aaaa') | The frequency map ensures efficient counting even when all characters are identical, properly accumulating pushes. |
| Input string with all unique characters (26 characters long) | The solution should correctly iterate through all characters and calculate the pushes needed based on their frequency/order. |
| Very long input string (potentially exceeding memory constraints) | Ensure the frequency map is implemented using space efficient data structures, and avoid unnecessary memory allocation. |
| String with a skewed distribution where some letters are very frequent while others are rare | The solution will prioritize less frequent letters to use with single pushes, leading to an optimized count. |
| Integer overflow when calculating total presses if input string is extremely long | Use a data type with a large range (e.g., long) to store the total number of presses to prevent overflow. |