Keyboard Row — Solution in Python, Java & C++
Keyboard Row solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. An easy problem on arrays and strings.
Keyboard Row is an easy coding problem on arrays, strings and hash table, asked in Amazon and MathWorks interviews.
- Difficulty: Easy
- Topics: Arrays, Strings, Hash Table
- Asked at: Amazon, MathWorks
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given an array of strings words, return those that can be typed using letters from only one row of an American QWERTY keyboard.
The rows are:
qwertyuiop
asdfghjkl
zxcvbnm
Case is ignored. Return the qualifying words in their original order.
Example 1
Input: words = ["Hello","Alaska","Dad","Peace"]
Output: ["Alaska","Dad"]
Example 2
Input: words = ["omk"]
Output: []
Example 3
Input: words = ["adsdf","sfd"]
Output: ["adsdf","sfd"]
Constraints
1 <= words.length <= 201 <= words[i].length <= 100words[i] consists of English letters, upper or lower case.
Hints for Keyboard Row
Hint 1
Map every letter to its row index once, up front.
Hint 2
A word qualifies when all its letters share the first letter's row.
Hint 3
Lowercase each letter before the lookup so case is ignored.
How to solve Keyboard Row
Reduce each letter to a row number, then a word qualifies exactly when its row numbers are all equal.
Approach
- Build a letter-to-row lookup from the three row strings.
- For each word, take the row of its first letter.
- Scan the remaining letters; if any differs, reject the word.
- Collect the survivors in input order.
Why it works
"Typed on one row" is precisely the statement that the row function is constant across the word, which the scan checks directly.
Complexity
- Time —
O(total characters) - Space —
O(1) — the lookup is 26 entries
Pitfalls
- Forgetting to lowercase rejects
"Dad", whose capitalDis not in the row strings. - Comparing against a fixed row rather than the word's own first-letter row hard-codes the wrong answer.
- The output must preserve the input order.
Reference solution
Python
from typing import List
def findWords(words: List[str]) -> List[str]:
rows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"]
row_of = {}
for r, letters in enumerate(rows):
for c in letters:
row_of[c] = r
out = []
for w in words:
r = row_of[w[0].lower()]
if all(row_of[c.lower()] == r for c in w):
out.append(w)
return outJava
public static String[] findWords(String[] words) {
String[] rows = { "qwertyuiop", "asdfghjkl", "zxcvbnm" };
int[] rowOf = new int[26];
for (int r = 0; r < rows.length; r++) {
for (int i = 0; i < rows[r].length(); i++) rowOf[rows[r].charAt(i) - 'a'] = r;
}
ArrayList<String> out = new ArrayList<>();
for (String w : words) {
int target = rowOf[Character.toLowerCase(w.charAt(0)) - 'a'];
boolean ok = true;
for (int i = 0; i < w.length(); i++) {
if (rowOf[Character.toLowerCase(w.charAt(i)) - 'a'] != target) { ok = false; break; }
}
if (ok) out.add(w);
}
return out.toArray(new String[0]);
}C++
vector<string> findWords(vector<string>& words) {
vector<string> rows = { "qwertyuiop", "asdfghjkl", "zxcvbnm" };
vector<int> rowOf(26, 0);
for (int r = 0; r < 3; r++) {
for (char c : rows[r]) rowOf[c - 'a'] = r;
}
vector<string> out;
for (auto& w : words) {
char first = w[0] >= 'A' && w[0] <= 'Z' ? (char) (w[0] + 32) : w[0];
int target = rowOf[first - 'a'];
bool ok = true;
for (char ch : w) {
char lc = ch >= 'A' && ch <= 'Z' ? (char) (ch + 32) : ch;
if (rowOf[lc - 'a'] != target) { ok = false; break; }
}
if (ok) out.push_back(w);
}
return out;
}JavaScript
var findWords = function(words) {
const rows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
const rowOf = {};
for (let r = 0; r < rows.length; r++) {
for (let i = 0; i < rows[r].length; i++) rowOf[rows[r].charAt(i)] = r;
}
const out = [];
for (let i = 0; i < words.length; i++) {
const w = words[i];
const r = rowOf[w.charAt(0).toLowerCase()];
let ok = true;
for (let j = 0; j < w.length; j++) {
if (rowOf[w.charAt(j).toLowerCase()] !== r) { ok = false; break; }
}
if (ok) out.push(w);
}
return out;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.