Facebook Pixel

1320. Minimum Distance to Type a Word Using Two Fingers

Problem Description

You have a keyboard layout where English uppercase letters are arranged in a grid pattern. The keyboard has 26 letters arranged with 6 letters per row (except the last row which has 2 letters). The letters are positioned as follows:

  • Row 0: A B C D E F (positions 0-5)
  • Row 1: G H I J K L (positions 6-11)
  • Row 2: M N O P Q R (positions 12-17)
  • Row 3: S T U V W X (positions 18-23)
  • Row 4: Y Z (positions 24-25)

Each letter has coordinates (row, column). For example:

  • Letter 'A' is at coordinate (0, 0)
  • Letter 'B' is at coordinate (0, 1)
  • Letter 'P' is at coordinate (2, 3)
  • Letter 'Z' is at coordinate (4, 1)

You need to type a given string word using two fingers. The distance between any two coordinates (x₁, y₁) and (x₂, y₂) is calculated using Manhattan distance: |x₁ - x₂| + |y₁ - y₂|.

Key rules:

  • You can use two fingers to type the word
  • The initial positions of your fingers are free (don't count toward the total distance)
  • Your fingers don't have to start at the first letter or first two letters
  • Each letter in the word must be typed in order
  • Only one finger moves to type each letter

The goal is to find the minimum total distance traveled by your fingers to type the entire word.

For example, if you need to type "CAKE":

  • You could position one finger initially at 'C' and another at 'A' (no cost for initial positioning)
  • Then move fingers optimally to type 'K' and 'E'
  • The total distance would be the sum of all movements made after the initial positioning

Return the minimum total distance required to type the given word using two fingers.

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

Intuition

The key insight is that at any point while typing, we need to know where both fingers are positioned to make optimal decisions about which finger to use for the next letter. This naturally leads to a dynamic programming approach where we track the positions of both fingers after typing each character.

Think about it this way: when we need to type the next letter, we have two choices - use finger 1 or use finger 2. The optimal choice depends on:

  1. Where each finger currently is
  2. How far each finger would need to move
  3. Where the remaining letters are (which affects future moves)

Since we can't predict all future moves easily, we can use dynamic programming to explore all possibilities and keep track of the minimum cost for each possible configuration.

The state representation becomes clear: f[i][j][k] represents "after typing the i-th character, what's the minimum distance if finger 1 is at position j and finger 2 is at position k?"

For the base case, when typing the first letter, one finger moves to that letter (with 0 cost since initial positions are free) while the other finger can be anywhere. This gives us all possible starting configurations.

For subsequent letters, we need to consider:

  • If we use finger 1 to type the current letter, finger 1 moves from its previous position to the new letter's position, while finger 2 stays put
  • If we use finger 2 to type the current letter, finger 2 moves while finger 1 stays put

The tricky part is that we need to track which finger was at the previous letter's position. If finger 1 was at position a (previous letter) and we move it to position b (current letter), then we add dist(a, b) to our cost. But if finger 2 was at position a, then we need to consider all possible previous positions of finger 1 to find the minimum cost path.

By building up the solution letter by letter and considering all possible finger configurations, we ensure we find the globally optimal solution rather than getting stuck in a locally optimal but globally suboptimal choice.

Learn more about Dynamic Programming patterns.

Solution Approach

The solution uses dynamic programming with a 3D state array to track all possible finger positions after typing each character.

State Definition:

  • f[i][j][k] represents the minimum distance after typing word[i], with finger 1 at position j and finger 2 at position k
  • Positions j and k range from 0 to 25 (representing letters A to Z)
  • Initialize all states to infinity

Distance Calculation: The dist(a, b) function calculates Manhattan distance between two letter positions:

  • Convert position to row/column: row = position // 6, column = position % 6
  • Distance = |row1 - row2| + |col1 - col2|

Base Case (First Letter): When typing word[0], we have two scenarios:

  • Finger 1 at word[0], finger 2 anywhere: f[0][word[0]][k] = 0 for all k ∈ [0, 25]
  • Finger 2 at word[0], finger 1 anywhere: f[0][k][word[0]] = 0 for all k ∈ [0, 25]

The cost is 0 because initial finger positions are free.

Transition (Subsequent Letters): For each letter word[i] (where i ≥ 1):

  • Let a = word[i-1] (previous letter position)
  • Let b = word[i] (current letter position)

We consider two main cases:

Case 1: Use finger 1 to type current letter (finger 1 moves to position b):

  • For each possible position j of finger 2:
    • If finger 1 was at position a previously: f[i][b][j] = min(f[i][b][j], f[i-1][a][j] + dist(a, b))
    • If finger 2 is at position a (i.e., j = a), then finger 2 typed the previous letter. We enumerate all possible previous positions k of finger 1: f[i][b][j] = min(f[i][b][j], f[i-1][k][a] + dist(k, b))

Case 2: Use finger 2 to type current letter (finger 2 moves to position b):

  • For each possible position j of finger 1:
    • If finger 2 was at position a previously: f[i][j][b] = min(f[i][j][b], f[i-1][j][a] + dist(a, b))
    • If finger 1 is at position a (i.e., j = a), then finger 1 typed the previous letter. We enumerate all possible previous positions k of finger 2: f[i][j][b] = min(f[i][j][b], f[i-1][a][k] + dist(k, b))

Final Answer: After processing all letters, the last letter must be at position word[n-1]. We find the minimum among:

  • All states where finger 1 is at the last letter: min(f[n-1][word[n-1]][j]) for all j
  • All states where finger 2 is at the last letter: min(f[n-1][j][word[n-1]]) for all j

The algorithm systematically explores all possible finger configurations and movement sequences, ensuring we find the globally optimal solution with time complexity O(n × 26²) and space complexity O(n × 26²).

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 typing the word "HI" to illustrate the solution approach.

First, let's identify the letter positions:

  • 'H' is at position 7 (row 1, column 1)
  • 'I' is at position 8 (row 1, column 2)

Step 1: Initialize the DP array

  • Create f[2][26][26] initialized to infinity
  • f[i][j][k] = minimum distance after typing character i, with finger 1 at position j and finger 2 at position k

Step 2: Base case - typing 'H' (word[0]) Since initial finger positions are free, we set:

  • Finger 1 at 'H', finger 2 anywhere: f[0][7][k] = 0 for all k ∈ [0, 25]
  • Finger 2 at 'H', finger 1 anywhere: f[0][j][7] = 0 for all j ∈ [0, 25]

This gives us 52 possible starting configurations, all with cost 0.

Step 3: Transition - typing 'I' (word[1]) Previous letter: a = 7 ('H') Current letter: b = 8 ('I') Distance from 'H' to 'I': dist(7, 8) = |1-1| + |1-2| = 1

Now we consider all valid previous states and calculate new states:

Case 1: Use finger 1 to type 'I' (finger 1 moves to position 8)

  • From state f[0][7][k] = 0 (finger 1 was at 'H'):
    • f[1][8][k] = min(∞, 0 + 1) = 1 for all k ≠ 7
  • When k = 7 (both fingers were at 'H'), we need to check all possible previous positions of finger 1:
    • From state f[0][j][7] = 0: f[1][8][7] = min(∞, 0 + dist(j, 8))
    • The minimum occurs when j = 7: f[1][8][7] = 0 + dist(7, 8) = 1

Case 2: Use finger 2 to type 'I' (finger 2 moves to position 8)

  • From state f[0][j][7] = 0 (finger 2 was at 'H'):
    • f[1][j][8] = min(∞, 0 + 1) = 1 for all j ≠ 7
  • When j = 7 (both fingers were at 'H'), we need to check all possible previous positions of finger 2:
    • From state f[0][7][k] = 0: f[1][7][8] = min(∞, 0 + dist(k, 8))
    • The minimum occurs when k = 7: f[1][7][8] = 0 + dist(7, 8) = 1

Step 4: Find the minimum distance The last letter 'I' is at position 8. We check:

  • States where finger 1 is at 'I': min(f[1][8][k]) for all k = min(1) = 1
  • States where finger 2 is at 'I': min(f[1][j][8]) for all j = min(1) = 1

Result: The minimum distance to type "HI" is 1.

This makes intuitive sense: we position both fingers initially at 'H' (free), then move one finger from 'H' to 'I' (distance = 1).

Solution Implementation

1class Solution:
2    def minimumDistance(self, word: str) -> int:
3        """
4        Calculate minimum distance to type a word using two fingers on a keyboard.
5        The keyboard layout is A-Z arranged in a 6x5 grid (last row has 2 letters).
6        """
7      
8        def calculate_distance(char1: int, char2: int) -> int:
9            """
10            Calculate Manhattan distance between two characters on the keyboard.
11          
12            Args:
13                char1: First character index (0-25 for A-Z)
14                char2: Second character index (0-25 for A-Z)
15          
16            Returns:
17                Manhattan distance between the two positions
18            """
19            row1, col1 = divmod(char1, 6)
20            row2, col2 = divmod(char2, 6)
21            return abs(row1 - row2) + abs(col1 - col2)
22      
23        word_length = len(word)
24      
25        # dp[i][left_finger][right_finger] represents minimum distance after typing
26        # word[0:i+1] with left finger at position left_finger and right finger at right_finger
27        dp = [[[float('inf')] * 26 for _ in range(26)] for _ in range(word_length)]
28      
29        # Initialize first character - can be typed by either finger with 0 cost
30        first_char_index = ord(word[0]) - ord('A')
31        for finger_pos in range(26):
32            dp[0][first_char_index][finger_pos] = 0  # Left finger typed first char
33            dp[0][finger_pos][first_char_index] = 0  # Right finger typed first char
34      
35        # Process each subsequent character
36        for i in range(1, word_length):
37            prev_char_index = ord(word[i - 1]) - ord('A')
38            curr_char_index = ord(word[i]) - ord('A')
39            distance_between_chars = calculate_distance(prev_char_index, curr_char_index)
40          
41            for other_finger in range(26):
42                # Case 1: Same finger that typed previous character types current character
43                # Left finger was at prev_char, moves to curr_char
44                dp[i][curr_char_index][other_finger] = min(
45                    dp[i][curr_char_index][other_finger],
46                    dp[i - 1][prev_char_index][other_finger] + distance_between_chars
47                )
48                # Right finger was at prev_char, moves to curr_char
49                dp[i][other_finger][curr_char_index] = min(
50                    dp[i][other_finger][curr_char_index],
51                    dp[i - 1][other_finger][prev_char_index] + distance_between_chars
52                )
53              
54                # Case 2: The other finger (not at prev_char) types current character
55                if other_finger == prev_char_index:
56                    for previous_position in range(26):
57                        distance_to_current = calculate_distance(previous_position, curr_char_index)
58                        # Left finger moves from previous_position to curr_char
59                        dp[i][curr_char_index][other_finger] = min(
60                            dp[i][curr_char_index][other_finger],
61                            dp[i - 1][previous_position][prev_char_index] + distance_to_current
62                        )
63                        # Right finger moves from previous_position to curr_char
64                        dp[i][other_finger][curr_char_index] = min(
65                            dp[i][other_finger][curr_char_index],
66                            dp[i - 1][prev_char_index][previous_position] + distance_to_current
67                        )
68      
69        # Find minimum distance among all valid final states
70        last_char_index = ord(word[-1]) - ord('A')
71      
72        # Minimum when left finger is at last character
73        min_left_finger = min(dp[word_length - 1][last_char_index])
74      
75        # Minimum when right finger is at last character
76        min_right_finger = min(dp[word_length - 1][j][last_char_index] for j in range(26))
77      
78        return int(min(min_left_finger, min_right_finger))
79
1class Solution {
2    public int minimumDistance(String word) {
3        int n = word.length();
4        final int INF = 1 << 30;
5      
6        // dp[i][j][k] represents the minimum distance to type first i+1 characters
7        // with left finger on character j and right finger on character k
8        int[][][] dp = new int[n][26][26];
9      
10        // Initialize all states with infinity
11        for (int[][] row : dp) {
12            for (int[] cell : row) {
13                Arrays.fill(cell, INF);
14            }
15        }
16      
17        // Base case: first character can be typed by either finger with 0 cost
18        // The other finger can be at any position
19        int firstChar = word.charAt(0) - 'A';
20        for (int j = 0; j < 26; ++j) {
21            dp[0][firstChar][j] = 0;  // Left finger types first char, right at position j
22            dp[0][j][firstChar] = 0;  // Right finger types first char, left at position j
23        }
24      
25        // Fill dp table for remaining characters
26        for (int i = 1; i < n; ++i) {
27            int prevChar = word.charAt(i - 1) - 'A';
28            int currChar = word.charAt(i) - 'A';
29            int distance = dist(prevChar, currChar);
30          
31            for (int j = 0; j < 26; ++j) {
32                // Case 1: Move the finger that was on previous character to current character
33                // Left finger was on prevChar, move it to currChar
34                dp[i][currChar][j] = Math.min(dp[i][currChar][j], dp[i - 1][prevChar][j] + distance);
35                // Right finger was on prevChar, move it to currChar
36                dp[i][j][currChar] = Math.min(dp[i][j][currChar], dp[i - 1][j][prevChar] + distance);
37              
38                // Case 2: Use the other finger (that wasn't on prevChar) to type currChar
39                if (j == prevChar) {
40                    for (int k = 0; k < 26; ++k) {
41                        int moveDistance = dist(k, currChar);
42                        // Left finger was at k, move it to currChar (right stays at prevChar=j)
43                        dp[i][currChar][j] = Math.min(dp[i][currChar][j], dp[i - 1][k][prevChar] + moveDistance);
44                        // Right finger was at k, move it to currChar (left stays at prevChar=j)
45                        dp[i][j][currChar] = Math.min(dp[i][j][currChar], dp[i - 1][prevChar][k] + moveDistance);
46                    }
47                }
48            }
49        }
50      
51        // Find minimum distance among all valid final states
52        // One finger must be on the last character
53        int result = INF;
54        int lastChar = word.charAt(n - 1) - 'A';
55        for (int j = 0; j < 26; ++j) {
56            result = Math.min(result, dp[n - 1][j][lastChar]);  // Right finger on last char
57            result = Math.min(result, dp[n - 1][lastChar][j]);  // Left finger on last char
58        }
59      
60        return result;
61    }
62  
63    /**
64     * Calculate Manhattan distance between two keys on a 6x5 keyboard layout
65     * Keys are numbered 0-25 (A-Z) in row-major order
66     */
67    private int dist(int a, int b) {
68        int row1 = a / 6, col1 = a % 6;
69        int row2 = b / 6, col2 = b % 6;
70        return Math.abs(row1 - row2) + Math.abs(col1 - col2);
71    }
72}
73
1class Solution {
2public:
3    int minimumDistance(string word) {
4        int wordLength = word.size();
5        const int INF = 1 << 30;  // Large value representing infinity
6      
7        // dp[i][leftFinger][rightFinger] = minimum distance to type first i+1 characters
8        // with left finger on position leftFinger and right finger on position rightFinger
9        vector<vector<vector<int>>> dp(wordLength, 
10                                       vector<vector<int>>(26, 
11                                                          vector<int>(26, INF)));
12      
13        // Initialize first character - can be typed with either finger at no cost
14        // The other finger can be at any position
15        for (int otherFinger = 0; otherFinger < 26; ++otherFinger) {
16            dp[0][word[0] - 'A'][otherFinger] = 0;  // First char typed with left finger
17            dp[0][otherFinger][word[0] - 'A'] = 0;  // First char typed with right finger
18        }
19      
20        // Process each subsequent character
21        for (int i = 1; i < wordLength; ++i) {
22            int prevChar = word[i - 1] - 'A';  // Previous character position
23            int currChar = word[i] - 'A';      // Current character to type
24            int moveDist = dist(prevChar, currChar);  // Distance between consecutive chars
25          
26            // Try all possible finger configurations
27            for (int otherFinger = 0; otherFinger < 26; ++otherFinger) {
28                // Case 1: Same finger that typed previous char types current char
29                // Left finger moves from prevChar to currChar, right stays at otherFinger
30                dp[i][currChar][otherFinger] = min(dp[i][currChar][otherFinger], 
31                                                   dp[i - 1][prevChar][otherFinger] + moveDist);
32              
33                // Right finger moves from prevChar to currChar, left stays at otherFinger
34                dp[i][otherFinger][currChar] = min(dp[i][otherFinger][currChar], 
35                                                   dp[i - 1][otherFinger][prevChar] + moveDist);
36              
37                // Case 2: The other finger (not at prevChar) types current char
38                if (otherFinger == prevChar) {
39                    // The finger at otherFinger position was the one that typed previous char
40                    // So we use the other finger to type current char
41                    for (int prevOtherFinger = 0; prevOtherFinger < 26; ++prevOtherFinger) {
42                        int otherFingerDist = dist(prevOtherFinger, currChar);
43                      
44                        // Left finger was at prevOtherFinger, moves to currChar
45                        dp[i][currChar][otherFinger] = min(dp[i][currChar][otherFinger], 
46                                                           dp[i - 1][prevOtherFinger][prevChar] + otherFingerDist);
47                      
48                        // Right finger was at prevOtherFinger, moves to currChar
49                        dp[i][otherFinger][currChar] = min(dp[i][otherFinger][currChar], 
50                                                           dp[i - 1][prevChar][prevOtherFinger] + otherFingerDist);
51                    }
52                }
53            }
54        }
55      
56        // Find minimum distance among all valid final configurations
57        // One finger must be at the last character position
58        int minDistance = INF;
59        int lastChar = word[wordLength - 1] - 'A';
60      
61        for (int otherFinger = 0; otherFinger < 26; ++otherFinger) {
62            minDistance = min(minDistance, dp[wordLength - 1][lastChar][otherFinger]);
63            minDistance = min(minDistance, dp[wordLength - 1][otherFinger][lastChar]);
64        }
65      
66        return minDistance;
67    }
68  
69    // Calculate Manhattan distance between two keys on a 6x5 keyboard layout
70    // Keys are arranged as: A=0, B=1, ..., Z=25
71    // Keyboard layout: 6 columns per row
72    int dist(int keyA, int keyB) {
73        int rowA = keyA / 6, colA = keyA % 6;
74        int rowB = keyB / 6, colB = keyB % 6;
75        return abs(rowA - rowB) + abs(colA - colB);
76    }
77};
78
1/**
2 * Calculates minimum distance to type a word using two fingers on a keyboard
3 * @param word - The word to type (uppercase letters only)
4 * @returns Minimum total distance fingers need to travel
5 */
6function minimumDistance(word: string): number {
7    const wordLength = word.length;
8    const INF = 1 << 30;  // Large value representing infinity
9  
10    // dp[i][leftFinger][rightFinger] = minimum distance to type first i+1 characters
11    // with left finger on position leftFinger and right finger on position rightFinger
12    const dp: number[][][] = Array(wordLength)
13        .fill(null)
14        .map(() => Array(26)
15            .fill(null)
16            .map(() => Array(26).fill(INF)));
17  
18    // Initialize first character - can be typed with either finger at no cost
19    // The other finger can be at any position
20    for (let otherFinger = 0; otherFinger < 26; otherFinger++) {
21        dp[0][word.charCodeAt(0) - 65][otherFinger] = 0;  // First char typed with left finger
22        dp[0][otherFinger][word.charCodeAt(0) - 65] = 0;  // First char typed with right finger
23    }
24  
25    // Process each subsequent character
26    for (let i = 1; i < wordLength; i++) {
27        const prevChar = word.charCodeAt(i - 1) - 65;  // Previous character position (A=0, B=1, etc.)
28        const currChar = word.charCodeAt(i) - 65;      // Current character to type
29        const moveDist = dist(prevChar, currChar);     // Distance between consecutive chars
30      
31        // Try all possible finger configurations
32        for (let otherFinger = 0; otherFinger < 26; otherFinger++) {
33            // Case 1: Same finger that typed previous char types current char
34            // Left finger moves from prevChar to currChar, right stays at otherFinger
35            dp[i][currChar][otherFinger] = Math.min(
36                dp[i][currChar][otherFinger], 
37                dp[i - 1][prevChar][otherFinger] + moveDist
38            );
39          
40            // Right finger moves from prevChar to currChar, left stays at otherFinger
41            dp[i][otherFinger][currChar] = Math.min(
42                dp[i][otherFinger][currChar], 
43                dp[i - 1][otherFinger][prevChar] + moveDist
44            );
45          
46            // Case 2: The other finger (not at prevChar) types current char
47            if (otherFinger === prevChar) {
48                // The finger at otherFinger position was the one that typed previous char
49                // So we use the other finger to type current char
50                for (let prevOtherFinger = 0; prevOtherFinger < 26; prevOtherFinger++) {
51                    const otherFingerDist = dist(prevOtherFinger, currChar);
52                  
53                    // Left finger was at prevOtherFinger, moves to currChar
54                    dp[i][currChar][otherFinger] = Math.min(
55                        dp[i][currChar][otherFinger], 
56                        dp[i - 1][prevOtherFinger][prevChar] + otherFingerDist
57                    );
58                  
59                    // Right finger was at prevOtherFinger, moves to currChar
60                    dp[i][otherFinger][currChar] = Math.min(
61                        dp[i][otherFinger][currChar], 
62                        dp[i - 1][prevChar][prevOtherFinger] + otherFingerDist
63                    );
64                }
65            }
66        }
67    }
68  
69    // Find minimum distance among all valid final configurations
70    // One finger must be at the last character position
71    let minDistance = INF;
72    const lastChar = word.charCodeAt(wordLength - 1) - 65;
73  
74    for (let otherFinger = 0; otherFinger < 26; otherFinger++) {
75        minDistance = Math.min(minDistance, dp[wordLength - 1][lastChar][otherFinger]);
76        minDistance = Math.min(minDistance, dp[wordLength - 1][otherFinger][lastChar]);
77    }
78  
79    return minDistance;
80}
81
82/**
83 * Calculate Manhattan distance between two keys on a 6x5 keyboard layout
84 * Keys are arranged as: A=0, B=1, ..., Z=25
85 * Keyboard layout: 6 columns per row
86 * @param keyA - First key position (0-25)
87 * @param keyB - Second key position (0-25)
88 * @returns Manhattan distance between the two keys
89 */
90function dist(keyA: number, keyB: number): number {
91    const rowA = Math.floor(keyA / 6);
92    const colA = keyA % 6;
93    const rowB = Math.floor(keyB / 6);
94    const colB = keyB % 6;
95    return Math.abs(rowA - rowB) + Math.abs(colA - colB);
96}
97

Time and Space Complexity

The time complexity is O(n × |Σ|²), where n is the length of the string word and |Σ| = 26 represents the size of the alphabet.

The analysis breaks down as follows:

  • The outer loop runs n times (for each character in the word)
  • For each iteration i, we iterate through all 26 possible positions for finger j, contributing O(|Σ|) operations
  • Within the special case when j == a, we have another loop through all 26 positions k, adding another O(|Σ|) factor
  • Overall, this gives us O(n × |Σ| × |Σ|) = O(n × |Σ|²)

The space complexity is O(n × |Σ|²) due to the 3-dimensional DP array f with dimensions [n][26][26], which stores the minimum distance for each position i in the word with the two fingers at positions [left_finger][right_finger].

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Incorrect Assumption About Initial Finger Positions

Pitfall: Many solutions incorrectly assume that fingers must start at the first one or two letters of the word, leading to suboptimal solutions.

Example: For the word "HAPPY", you might assume:

  • Finger 1 starts at 'H', Finger 2 starts at 'A'
  • Or both fingers start at 'H'

Why it's wrong: The problem states that initial finger positions are free (cost = 0). Fingers can start anywhere on the keyboard, not necessarily at the beginning letters.

Correct Approach: Initialize the DP state for the first letter with both possibilities:

  • One finger at the first letter, other finger anywhere (cost = 0)
  • This allows the algorithm to find the optimal starting position for the idle finger

2. Mishandling the Transition Between Letters

Pitfall: Failing to correctly track which finger typed the previous letter when calculating transitions.

Problematic Code Example:

# WRONG: Only considering the case where the same finger continues typing
dp[i][curr][other] = dp[i-1][prev][other] + dist(prev, curr)

Why it's wrong: This doesn't account for the case where the other finger (currently at position other) might have typed the previous letter.

Correct Implementation:

# Must check if other_finger is at prev_char position
if other_finger == prev_char_index:
    # The other finger typed previous letter, so we need to consider
    # all possible previous positions of the current moving finger
    for previous_position in range(26):
        distance = calculate_distance(previous_position, curr_char_index)
        dp[i][curr_char_index][other_finger] = min(
            dp[i][curr_char_index][other_finger],
            dp[i-1][previous_position][prev_char_index] + distance
        )

3. Space Optimization Trap

Pitfall: Attempting to optimize space by using only 2D DP array instead of 3D.

Problematic Approach:

# WRONG: Trying to use dp[finger1_pos][finger2_pos] without tracking progress
dp = [[float('inf')] * 26 for _ in range(26)]

Why it fails: Without tracking which character we're currently typing (the i dimension), we lose critical information about the sequence and can't correctly compute transitions.

Solution: Maintain the full 3D state or use rolling array optimization:

# Option 1: Full 3D array (shown in solution)
dp = [[[float('inf')] * 26 for _ in range(26)] for _ in range(word_length)]

# Option 2: Rolling array optimization (if space is critical)
prev_dp = [[float('inf')] * 26 for _ in range(26)]
curr_dp = [[float('inf')] * 26 for _ in range(26)]
# Swap prev_dp and curr_dp after each iteration

4. Incorrect Distance Calculation

Pitfall: Using Euclidean distance or incorrect grid mapping.

Wrong Example:

# WRONG: Using Euclidean distance
import math
distance = math.sqrt((row1 - row2)**2 + (col1 - col2)**2)

# WRONG: Incorrect grid layout (assuming 5 columns)
row, col = divmod(char_index, 5)

Correct Approach:

# Manhattan distance with 6 columns per row
row, col = divmod(char_index, 6)
distance = abs(row1 - row2) + abs(col1 - col2)

5. Edge Case: Single Character Word

Pitfall: Not handling words with length 1 correctly.

Issue: The algorithm might fail or return incorrect results for single-character words.

Solution: The current implementation handles this correctly by:

  • Initializing both finger positions for the first (and only) character
  • Returning 0 as the minimum distance (no movement needed after initial positioning)

Test Case:

assert minimumDistance("A") == 0
assert minimumDistance("Z") == 0
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

The three-steps of Depth First Search are:

  1. Identify states;
  2. Draw the state-space tree;
  3. DFS on the state-space tree.

Recommended Readings

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

Load More