1320. Minimum Distance to Type a Word Using Two Fingers
Minimum Distance to Type a Word
Using Two Fingers
Given a keyboard layout and a target word, find the minimum total Manhattan distance your two fingers need to travel to type the entire word — starting from any position for free.
You have a special keyboard with all 26 lowercase English letters laid out in a 4×6 grid (A–F on row 0, G–L on row 1, M–R on row 2, S–X on row 3, Y–Z on row 4).
You want to type a string word using two fingers. The distance to move a finger from key i to key j is the Manhattan distance: |row_i - row_j| + |col_i - col_j|. You can start both fingers anywhere for free (zero cost).
Return the minimum total distance to type the entire word.
C → Place Finger 1 +0Total cost so far: 0
A → Move Finger 1 from C→A +2Finger 2 stays unplaced. Total cost: 2
K → Place Finger 2 on K +0E → Move Finger 2 from K→E +1Final cost: 2 + 1 = 3 ✓
dp[j] = minimum cost where one finger is on the current character and the other finger is at position j (26 = not yet placed).
| After typing → | — (free) | A (0) | C (2) | K (10) | E (4) |
|---|---|---|---|---|---|
| C | 0 | ∞ | ∞ | ∞ | ∞ |
| A | 2 | ∞ | 0 | ∞ | ∞ |
| K | 7 | 2 | 5 | ∞ | ∞ |
| E ✓ | 8 | 3 | 6 | 6 | ∞ |
class Solution { public int minimumDistance(String word) { // dp[j] = min cost: one finger on word[i-1], other at letter j // j = 26 → other finger not yet placed int[] dp = new int[27]; Arrays.fill(dp, Integer.MAX_VALUE); dp[26] = 0; // start: both fingers unplaced for (int i = 1; i < word.length(); i++) { int prev = word.charAt(i - 1) - 'A'; int curr = word.charAt(i) - 'A'; int[] next = new int[27]; Arrays.fill(next, Integer.MAX_VALUE); for (int j = 0; j <= 26; j++) { if (dp[j] == Integer.MAX_VALUE) continue; // Choice 1: move the finger on prev → curr // other finger stays at j next[j] = Math.min(next[j], dp[j] + dist(prev, curr)); // Choice 2: move the other finger (at j) → curr // finger on prev becomes the new "other" next[prev] = Math.min(next[prev], dp[j] + dist(j, curr)); } dp = next; } int ans = Integer.MAX_VALUE; for (int cost : dp) ans = Math.min(ans, cost); return ans; } private int dist(int a, int b) { if (a == 26) return 0; // unplaced → free to place anywhere return Math.abs(a / 6 - b / 6) + Math.abs(a % 6 - b % 6); } }
j == 26 (finger not placed), dist() returns 0 — placing a finger anywhere is always free, matching the problem constraints.