1165. Single-Row Keyboard 🔒
Problem Description
You have a special keyboard where all keys are arranged in a single row. The keyboard layout is given as a string keyboard
of length 26, where each character represents a key and its position (index 0 to 25) indicates where it is located on the keyboard.
Your finger starts at position 0 on the keyboard. To type a character, you need to move your finger from its current position to the position of the desired character. The time required to move from position i
to position j
is calculated as the absolute difference |i - j|
.
Given a string word
that you want to type, calculate the total time needed to type the entire word using one finger.
For example, if the keyboard is "abcdefghijklmnopqrstuvwxyz"
and you want to type "cba"
:
- Start at position 0
- Move to 'c' at position 2: time = |2 - 0| = 2
- Move to 'b' at position 1: time = |1 - 2| = 1
- Move to 'a' at position 0: time = |0 - 1| = 1
- Total time = 2 + 1 + 1 = 4
The solution uses a hash table to map each character to its position on the keyboard. Then it iterates through each character in word
, calculating the distance from the current finger position to the target character's position, accumulating the total time, and updating the finger position after each character is typed.
Intuition
The key insight is that we need to track the movement of our finger across the keyboard as we type each character. Since the keyboard is a one-dimensional row, the distance between any two positions is simply the absolute difference between their indices.
To efficiently find where each character is located on the keyboard, we need a way to quickly look up the position of any character. Instead of searching through the keyboard string every time we need to type a character, we can preprocess the keyboard layout by creating a mapping from each character to its position. This gives us O(1) lookup time for each character.
Once we have this mapping, the problem becomes straightforward: we simulate the typing process. We keep track of where our finger currently is (starting at position 0), and for each character we want to type:
- Look up where that character is on the keyboard
- Calculate how far we need to move (absolute difference between current and target positions)
- Add this distance to our total time
- Update our finger's position to the new location
The total time is just the sum of all these individual movements. This approach naturally handles the sequential nature of typing - we can't skip ahead or type multiple characters simultaneously, so we must account for each movement from one character to the next.
Solution Approach
We can implement this solution using a hash table to store the position of each character on the keyboard.
First, we create a dictionary pos
where each key is a character from the keyboard string and its value is the character's index position. This is done with a dictionary comprehension: pos = {c: i for i, c in enumerate(keyboard)}
. This preprocessing step allows us to look up any character's position in O(1) time.
Next, we initialize two variables:
ans
to accumulate the total time (starting at 0)i
to track the current finger position (starting at 0)
Then we iterate through each character c
in the word we want to type:
- Look up the target position using
pos[c]
- Calculate the distance moved as
abs(pos[c] - i)
and add it toans
- Update the current finger position:
i = pos[c]
After processing all characters in the word, ans
contains the total time needed to type the entire word.
The time complexity is O(n + m) where n is the length of the keyboard (always 26) and m is the length of the word. The space complexity is O(1) since the hash table always stores exactly 26 character-position pairs.
This approach efficiently simulates the typing process by tracking finger movement across the keyboard and accumulating the distances traveled between consecutive characters.
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 to illustrate the solution approach.
Given:
keyboard = "pqrstuvwxyzabcdefghijklmno"
word = "cat"
Step 1: Build the position mapping
First, we create a hash table to map each character to its position on the keyboard:
pos = { 'p': 0, 'q': 1, 'r': 2, 's': 3, 't': 4, 'u': 5, 'v': 6, 'w': 7, 'x': 8, 'y': 9, 'z': 10, 'a': 11, 'b': 12, 'c': 13, 'd': 14, 'e': 15, 'f': 16, 'g': 17, 'h': 18, 'i': 19, 'j': 20, 'k': 21, 'l': 22, 'm': 23, 'n': 24, 'o': 25 }
Step 2: Initialize variables
ans = 0
(total time accumulated)i = 0
(current finger position, starting at index 0)
Step 3: Process each character in "cat"
Character 'c':
- Look up position:
pos['c'] = 13
- Calculate distance:
|13 - 0| = 13
- Update total time:
ans = 0 + 13 = 13
- Update finger position:
i = 13
Character 'a':
- Look up position:
pos['a'] = 11
- Calculate distance:
|11 - 13| = 2
- Update total time:
ans = 13 + 2 = 15
- Update finger position:
i = 11
Character 't':
- Look up position:
pos['t'] = 4
- Calculate distance:
|4 - 11| = 7
- Update total time:
ans = 15 + 7 = 22
- Update finger position:
i = 4
Step 4: Return the result
The total time needed to type "cat" is 22.
This example demonstrates how the algorithm tracks the finger's movement across the keyboard, calculating the distance for each character transition and accumulating the total time required.
Solution Implementation
1class Solution:
2 def calculateTime(self, keyboard: str, word: str) -> int:
3 # Create a dictionary mapping each character to its position on the keyboard
4 char_to_position = {char: index for index, char in enumerate(keyboard)}
5
6 # Initialize total time and current finger position (starts at index 0)
7 total_time = 0
8 current_position = 0
9
10 # Process each character in the word
11 for char in word:
12 # Calculate time as distance from current position to target character position
13 total_time += abs(char_to_position[char] - current_position)
14
15 # Update current finger position to where we just typed
16 current_position = char_to_position[char]
17
18 return total_time
19
1class Solution {
2 public int calculateTime(String keyboard, String word) {
3 // Create an array to store the position of each character on the keyboard
4 // Index represents the character (0 for 'a', 1 for 'b', etc.)
5 // Value represents the position on the keyboard
6 int[] charPositions = new int[26];
7
8 // Map each character to its position on the keyboard
9 for (int i = 0; i < 26; i++) {
10 char currentChar = keyboard.charAt(i);
11 int charIndex = currentChar - 'a'; // Convert character to index (0-25)
12 charPositions[charIndex] = i;
13 }
14
15 // Initialize total time and current finger position
16 int totalTime = 0;
17 int currentPosition = 0; // Finger starts at position 0
18
19 // Calculate time for typing each character in the word
20 for (int i = 0; i < word.length(); i++) {
21 // Get the target position for the current character
22 char currentChar = word.charAt(i);
23 int charIndex = currentChar - 'a';
24 int targetPosition = charPositions[charIndex];
25
26 // Add the distance from current position to target position
27 totalTime += Math.abs(currentPosition - targetPosition);
28
29 // Update current finger position
30 currentPosition = targetPosition;
31 }
32
33 return totalTime;
34 }
35}
36
1class Solution {
2public:
3 int calculateTime(string keyboard, string word) {
4 // Create an array to store the position of each character on the keyboard
5 // charPosition[i] represents the index position of character ('a' + i) on the keyboard
6 int charPosition[26];
7
8 // Build the position mapping for each character in the keyboard
9 for (int index = 0; index < 26; ++index) {
10 charPosition[keyboard[index] - 'a'] = index;
11 }
12
13 // Initialize total time and current finger position
14 int totalTime = 0;
15 int currentPosition = 0; // Finger starts at position 0
16
17 // Calculate time for typing each character in the word
18 for (char& character : word) {
19 // Get the target position for the current character
20 int targetPosition = charPosition[character - 'a'];
21
22 // Add the time (distance) to move from current position to target position
23 totalTime += abs(currentPosition - targetPosition);
24
25 // Update current finger position
26 currentPosition = targetPosition;
27 }
28
29 return totalTime;
30 }
31};
32
1/**
2 * Calculates the total time needed to type a word on a custom keyboard layout
3 * @param keyboard - A string of 26 lowercase letters representing the keyboard layout
4 * @param word - The word to be typed
5 * @returns The total time (distance) needed to type the word
6 */
7function calculateTime(keyboard: string, word: string): number {
8 // Create an array to store the position of each letter on the keyboard
9 // Index represents the letter (a=0, b=1, ..., z=25), value represents its position on keyboard
10 const letterPositions: number[] = Array(26).fill(0);
11
12 // Map each letter to its position on the keyboard
13 for (let i = 0; i < 26; i++) {
14 // Get the letter's ASCII value minus 97 (ASCII of 'a') to get index 0-25
15 const letterIndex = keyboard.charCodeAt(i) - 97;
16 letterPositions[letterIndex] = i;
17 }
18
19 // Initialize total time and current finger position (starts at position 0)
20 let totalTime = 0;
21 let currentPosition = 0;
22
23 // Calculate time for each character in the word
24 for (const character of word) {
25 // Get the target position of the current character on the keyboard
26 const targetPosition = letterPositions[character.charCodeAt(0) - 97];
27
28 // Add the distance from current position to target position
29 totalTime += Math.abs(currentPosition - targetPosition);
30
31 // Update current position to the target position
32 currentPosition = targetPosition;
33 }
34
35 return totalTime;
36}
37
Time and Space Complexity
The time complexity is O(n + k)
where n
is the length of the string word
and k
is the length of the keyboard
string (which is 26 for all lowercase letters). The O(k)
comes from creating the position dictionary by iterating through the keyboard string, and O(n)
comes from iterating through each character in the word. Since k
is constant (26), this simplifies to O(n)
.
The space complexity is O(k)
or O(26)
= O(1)
where k
represents the size of the character set. The position dictionary pos
stores at most 26 key-value pairs (one for each letter in the keyboard). Since this is a constant amount of space regardless of input size, it can also be expressed as O(C)
where C = 26
is the size of the character set.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Update the Current Position
A frequent mistake is calculating the distance correctly but forgetting to update the finger's current position after typing each character. This leads to incorrect distance calculations for subsequent characters.
Incorrect Implementation:
def calculateTime(self, keyboard: str, word: str) -> int:
char_to_position = {char: index for index, char in enumerate(keyboard)}
total_time = 0
current_position = 0
for char in word:
total_time += abs(char_to_position[char] - current_position)
# MISTAKE: Forgot to update current_position!
return total_time
This code would always calculate distances from position 0, giving wrong results for any word with more than one character.
Correct Solution: Always update the current position after calculating the distance:
for char in word:
total_time += abs(char_to_position[char] - current_position)
current_position = char_to_position[char] # Don't forget this line!
2. Starting from the Wrong Initial Position
Another pitfall is misunderstanding the initial finger position. The problem states the finger starts at position 0 (the first character of the keyboard), not at the position of the first character in the word.
Incorrect Implementation:
def calculateTime(self, keyboard: str, word: str) -> int:
char_to_position = {char: index for index, char in enumerate(keyboard)}
# MISTAKE: Starting at the first character of the word
current_position = char_to_position[word[0]]
total_time = current_position # Distance from 0 to first character
for i in range(1, len(word)):
total_time += abs(char_to_position[word[i]] - current_position)
current_position = char_to_position[word[i]]
return total_time
While this might seem logical, it adds unnecessary complexity and can lead to index errors if the word is empty.
Correct Solution: Always start from position 0 and let the loop handle all characters uniformly:
current_position = 0 # Always start at position 0
for char in word: # Process all characters the same way
total_time += abs(char_to_position[char] - current_position)
current_position = char_to_position[char]
3. Not Handling Edge Cases
Failing to consider edge cases like an empty word string can cause errors.
Potential Issue:
If word
is empty, the code should return 0 (no time needed to type nothing). The provided solution handles this correctly because the loop simply doesn't execute, and total_time
remains 0.
Best Practice: While the current solution handles empty strings naturally, you could add explicit validation if needed:
if not word: return 0
These pitfalls highlight the importance of careful state management and understanding the problem's initial conditions when implementing simulation-based algorithms.
Which type of traversal does breadth first search do?
Recommended Readings
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
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!