Facebook Pixel

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 (where k 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.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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 add k * 8 to our total
  • Handle any remaining letters (n % 8) which all require k presses where k is the next position depth

Learn more about Greedy and Math patterns.

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:

  1. Initialize variables:

    • n = len(word): Get the total number of distinct letters
    • ans = 0: Initialize the answer to track total key presses
    • k = 1: Start with position 1 (first position on each key)
  2. 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 requiring k presses)
    • After each round, increment k since the next round will place letters at the next position depth
  3. 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 add k * (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

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 Evaluator

Example 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 execute ans += 1 * n, which gives us n
  • 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!

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of the following problems can be solved with backtracking (select multiple)


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More