3014. Minimum Number of Pushes to Type Word I
Problem Description
You are given a string word
containing distinct lowercase English letters.
On a telephone keypad, keys 2-9 can be mapped to collections of lowercase English letters. To type a letter, you need to press its corresponding key a certain number of times based on the letter's position in that key's collection. For example, if key 2 is mapped to ["a","b","c"]
:
- Press once to type "a"
- Press twice to type "b"
- Press three times to type "c"
You have the freedom to remap keys 2-9 to any distinct collections of letters. Each key can hold any number of letters, but every letter must be assigned to exactly one key.
Your task is to find the optimal key mapping that minimizes the total number of key presses needed to type the entire string word
.
Since all letters in word
are distinct, the greedy approach distributes letters evenly across the 8 available keys (keys 2-9). The solution calculates the minimum pushes by:
- Assigning the first 8 letters to positions requiring 1 press each
- Assigning the next 8 letters to positions requiring 2 presses each
- Continuing this pattern for all letters in the word
The formula implemented is:
- For every complete group of 8 letters: add
k * 8
pushes (wherek
is the position depth) - For remaining letters: add
k * (n % 8)
pushes
Return the minimum number of pushes needed to type word
after optimally remapping the keys.
Intuition
Since all letters in the word are distinct, we don't need to worry about frequency - each letter appears exactly once. This simplifies our problem significantly.
The key insight is that we have 8 available keys (keys 2-9) and we want to minimize the total number of presses. Each key can hold multiple letters, where:
- The 1st letter on a key requires 1 press
- The 2nd letter on a key requires 2 presses
- The 3rd letter on a key requires 3 presses
- And so on...
To minimize total presses, we should distribute letters as evenly as possible across all 8 keys. Why? Because having letters at lower positions (requiring fewer presses) on multiple keys is better than stacking many letters on fewer keys.
Think of it like this: if we have 16 letters, we could either:
- Put all 16 on one key: requiring
1+2+3+...+16 = 136
presses - Put 2 on each of the 8 keys: requiring
8×1 + 8×2 = 24
presses
The second option is clearly better!
This leads to the greedy strategy:
- First 8 letters go to position 1 on each key (1 press each)
- Next 8 letters go to position 2 on each key (2 presses each)
- Continue this pattern...
The calculation becomes straightforward:
- Count how many complete "rounds" of 8 letters we have:
n // 8
- For each complete round
k
, we addk * 8
to our total - Handle any remaining letters (
n % 8
) which all requirek
presses wherek
is the next position depth
Solution Approach
The implementation follows a straightforward greedy approach based on our intuition that letters should be distributed evenly across the 8 available keys.
Let's walk through the algorithm step by step:
-
Initialize variables:
n = len(word)
: Get the total number of distinct lettersans = 0
: Initialize the answer to track total key pressesk = 1
: Start with position 1 (first position on each key)
-
Process complete rounds of 8 letters:
for _ in range(n // 8): ans += k * 8 k += 1
n // 8
gives us the number of complete rounds where we can fill all 8 keys- For each round, we add
k * 8
to the answer (8 letters each requiringk
presses) - After each round, increment
k
since the next round will place letters at the next position depth
-
Handle remaining letters:
ans += k * (n % 8)
n % 8
gives us the remaining letters after complete rounds- These remaining letters all go to position
k
on different keys - Each requires
k
presses, so we addk * (n % 8)
to our total
Example walkthrough:
- If
word
has 18 letters:- First 8 letters: position 1 on keys 2-9 →
1 * 8 = 8
presses - Next 8 letters: position 2 on keys 2-9 →
2 * 8 = 16
presses - Last 2 letters: position 3 on keys 2-3 →
3 * 2 = 6
presses - Total:
8 + 16 + 6 = 30
presses
- First 8 letters: position 1 on keys 2-9 →
The algorithm has O(n/8) time complexity for the loop iterations and O(1) space complexity as we only use a few variables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example with word = "abcdefghijklm"
(13 distinct letters).
Step 1: Initial Setup
- We have 13 letters to distribute across 8 keys (keys 2-9)
- Initialize:
n = 13
,ans = 0
,k = 1
Step 2: Calculate Complete Rounds
- Number of complete rounds:
n // 8 = 13 // 8 = 1
- We can fill all 8 keys once completely
Step 3: Process First Round (k=1)
- Assign letters a-h to position 1 on keys 2-9:
- Key 2: 'a' (1 press)
- Key 3: 'b' (1 press)
- Key 4: 'c' (1 press)
- Key 5: 'd' (1 press)
- Key 6: 'e' (1 press)
- Key 7: 'f' (1 press)
- Key 8: 'g' (1 press)
- Key 9: 'h' (1 press)
- Total presses for this round:
1 × 8 = 8
- Update:
ans = 8
,k = 2
Step 4: Handle Remaining Letters
- Remaining letters:
n % 8 = 13 % 8 = 5
letters (i, j, k, l, m) - These go to position 2 on keys 2-6:
- Key 2: 'a', 'i' → 'i' requires 2 presses
- Key 3: 'b', 'j' → 'j' requires 2 presses
- Key 4: 'c', 'k' → 'k' requires 2 presses
- Key 5: 'd', 'l' → 'l' requires 2 presses
- Key 6: 'e', 'm' → 'm' requires 2 presses
- Total presses for remaining:
2 × 5 = 10
- Update:
ans = 8 + 10 = 18
Final Answer: 18 presses
The optimal mapping minimizes presses by spreading letters evenly, ensuring no key gets overloaded while others remain empty.
Solution Implementation
1class Solution:
2 def minimumPushes(self, word: str) -> int:
3 """
4 Calculate the minimum number of button pushes needed to type a word.
5
6 Strategy: Assign letters to 8 keys (keys 2-9 on a phone keypad).
7 - First 8 letters: 1 push each (one letter per key)
8 - Next 8 letters: 2 pushes each (second letter on each key)
9 - Next 8 letters: 3 pushes each (third letter on each key)
10 - And so on...
11
12 Args:
13 word: The input string to be typed
14
15 Returns:
16 The minimum number of button pushes required
17 """
18 word_length = len(word)
19 total_pushes = 0
20 push_multiplier = 1 # Number of pushes needed for current group of 8 letters
21
22 # Process complete groups of 8 letters
23 complete_groups = word_length // 8
24 for _ in range(complete_groups):
25 total_pushes += push_multiplier * 8 # Each of 8 letters needs push_multiplier pushes
26 push_multiplier += 1 # Next group needs one more push per letter
27
28 # Process remaining letters (less than 8)
29 remaining_letters = word_length % 8
30 total_pushes += push_multiplier * remaining_letters
31
32 return total_pushes
33
1class Solution {
2 public int minimumPushes(String word) {
3 // Get the length of the input word
4 int wordLength = word.length();
5
6 // Initialize total pushes counter
7 int totalPushes = 0;
8
9 // Initialize the push count per character (starts at 1, increments for each layer)
10 int pushesPerChar = 1;
11
12 // Process complete groups of 8 characters
13 // Each group represents one layer of characters on 8 buttons
14 int completeGroups = wordLength / 8;
15 for (int groupIndex = 0; groupIndex < completeGroups; groupIndex++) {
16 // Add pushes for 8 characters in this layer
17 // Each character requires 'pushesPerChar' pushes
18 totalPushes += pushesPerChar * 8;
19
20 // Move to next layer (requires one more push per character)
21 pushesPerChar++;
22 }
23
24 // Process remaining characters (less than 8)
25 // These go on the next layer with current push count
26 int remainingChars = wordLength % 8;
27 totalPushes += pushesPerChar * remainingChars;
28
29 return totalPushes;
30 }
31}
32
1class Solution {
2public:
3 int minimumPushes(string word) {
4 // Get the total number of characters in the word
5 int wordLength = word.size();
6
7 // Initialize the total number of pushes required
8 int totalPushes = 0;
9
10 // Initialize the current push count per character
11 // (increases after every 8 characters are assigned)
12 int pushesPerChar = 1;
13
14 // Process complete groups of 8 characters
15 // Each group uses all 8 available keys
16 int completeGroups = wordLength / 8;
17 for (int groupIndex = 0; groupIndex < completeGroups; ++groupIndex) {
18 // Add pushes for this group (8 characters * current push count)
19 totalPushes += pushesPerChar * 8;
20
21 // Increment push count for the next group
22 ++pushesPerChar;
23 }
24
25 // Process the remaining characters (less than 8)
26 int remainingChars = wordLength % 8;
27 totalPushes += pushesPerChar * remainingChars;
28
29 return totalPushes;
30 }
31};
32
1/**
2 * Calculates the minimum number of button pushes needed to type a word
3 * on a phone keypad where letters are distributed across 8 keys (2-9).
4 * Each key can hold multiple letters, and the push count increases
5 * based on the position of the letter on that key.
6 *
7 * @param word - The input string to be typed
8 * @returns The minimum number of button pushes required
9 */
10function minimumPushes(word: string): number {
11 // Get the length of the input word
12 const wordLength: number = word.length;
13
14 // Initialize the total number of pushes
15 let totalPushes: number = 0;
16
17 // Track the current layer/position of letters on keys (1st, 2nd, 3rd, etc.)
18 let currentLayer: number = 1;
19
20 // Calculate pushes for complete groups of 8 letters
21 // Each group of 8 letters fills all 8 keys at the current layer
22 const completeGroups: number = Math.floor(wordLength / 8);
23
24 for (let groupIndex = 0; groupIndex < completeGroups; groupIndex++) {
25 // Add pushes for 8 letters at the current layer
26 // (currentLayer pushes per letter × 8 letters)
27 totalPushes += currentLayer * 8;
28
29 // Move to the next layer for the next group
30 currentLayer++;
31 }
32
33 // Calculate pushes for remaining letters (less than 8)
34 const remainingLetters: number = wordLength % 8;
35 totalPushes += currentLayer * remainingLetters;
36
37 return totalPushes;
38}
39
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the string word
. While the reference answer states O(n/8)
, this is technically equivalent to O(n)
in Big-O notation since constant factors are dropped. The loop runs n // 8
times, which means it executes approximately n/8
iterations. Each iteration performs constant time operations, resulting in O(n/8) = O(n)
time complexity.
The space complexity is O(1)
. The algorithm only uses a fixed amount of extra space for variables n
, ans
, and k
, regardless of the input size. No additional data structures that scale with the input are created.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Misunderstanding the Problem Constraints
The Mistake: Many developers initially assume they need to consider the frequency of each letter in the word, leading to unnecessarily complex solutions involving counting characters and sorting by frequency.
Why It Happens: The problem states that all letters in word
are distinct, but this crucial detail is often overlooked. Developers might write code like:
# Incorrect approach - overcomplicating with frequency counting
from collections import Counter
class Solution:
def minimumPushes(self, word: str) -> int:
freq = Counter(word)
sorted_chars = sorted(freq.items(), key=lambda x: x[1], reverse=True)
# ... complex logic to assign based on frequency
The Fix: Remember that since all letters are distinct, each letter appears exactly once. The problem reduces to simply distributing n
distinct items across 8 keys optimally, which is achieved by the simple greedy approach shown in the solution.
Pitfall 2: Off-by-One Errors in Position Calculation
The Mistake: Starting the position counter k
at 0 instead of 1, or incorrectly calculating which position a letter should occupy:
# Incorrect - starting k at 0
def minimumPushes(self, word: str) -> int:
n = len(word)
ans = 0
k = 0 # Wrong! First position should be 1, not 0
for _ in range(n // 8):
ans += k * 8
k += 1
ans += k * (n % 8)
return ans
Why It Happens: In programming, we often use 0-based indexing, but in this problem, the first letter on a key requires 1 press, not 0 presses.
The Fix: Always initialize k = 1
to represent that the first position requires one key press.
Pitfall 3: Incorrect Handling of Edge Cases
The Mistake: Not properly handling cases where the word length is less than 8:
# Potentially problematic if not careful
def minimumPushes(self, word: str) -> int:
n = len(word)
if n <= 8:
return n # Correct, but might forget this optimization
# ... rest of the code
Why It Happens: The general formula works for all cases, but developers might try to add special case handling and introduce bugs.
The Fix: The beauty of the provided solution is that it naturally handles all cases correctly:
- If
n < 8
: The loop runs 0 times, and we only executeans += 1 * n
, which gives usn
- If
n = 8
: The loop runs once adding 8, and the remainder is 0 - If
n > 8
: The general case works as expected
No special case handling needed!
Which of the following problems can be solved with backtracking (select multiple)
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Don’t Miss This!