Keyboard Row

Easy
593.

Keyboard Row

Keyboard Row is an easy coding problem on arrays, strings and hash table, asked in Amazon and MathWorks interviews.

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 <= 20
  • 1 <= words[i].length <= 100
  • words[i] consists of English letters, upper or lower case.
Write your solution here. Running it against the tests needs a free account — what you type comes with you.Sign in to run
/**
 * @param {string[]} words
 * @return {string[]}
 */
var findWords = function(words) {
    // Write your code here
    
};

Sign in to run your own test cases

Sign in

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 <= 20
  • 1 <= words[i].length <= 100
  • words[i] consists of English letters, upper or lower case.

Hints for Keyboard Row

  1. Hint 1

    Map every letter to its row index once, up front.

  2. Hint 2

    A word qualifies when all its letters share the first letter's row.

  3. 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

  1. Build a letter-to-row lookup from the three row strings.
  2. For each word, take the row of its first letter.
  3. Scan the remaining letters; if any differs, reject the word.
  4. 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 capital D is 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 out

Java

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.

All 1199 arrays problems · the whole catalogue

Learn the technique: Arrays · Strings