Skip to content

Commit 107f0b7

Browse files
authored
Merge pull request #54 from NemoRaphtalia/Problem500
Solution #500 - Daniel - 16/06/2025
2 parents 4ace165 + e72454b commit 107f0b7

File tree

3 files changed

+173
-0
lines changed

3 files changed

+173
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# 500. Keyboard Row
2+
3+
**Difficulty:** *Easy*
4+
**Category:** *Strings*
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/keyboard-row/description/)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
*Given an array of strings, return the words that can be typed using letters of the alphabet on only one row of a standard American keyboard.*
12+
13+
*The keyboard rows are:<br>
14+
Top row: qwertyuiop<br>
15+
Middle row: asdfghjkl<br>
16+
Bottom row: zxcvbnm*
17+
18+
*You may return the answer in any order.*
19+
20+
---
21+
22+
## 💡 Approach & Key Insights
23+
24+
*The main idea is to check for each word if all its characters belong to the same keyboard row. <br>
25+
By converting each word to lowercase and then to a set, we can easily determine if its characters are a subset of any one row.*
26+
27+
---
28+
29+
## 🛠️ Breakdown of Approaches
30+
31+
### 1️⃣ Brute Force / Naive Approach
32+
33+
- **Explanation:** *For each word, check if every character belongs to the same keyboard row by comparing each character to the characters in all three rows. This involves checking character-by-character for each word.*
34+
- **Time Complexity:** *O(n * m) - where n is the number of words and m is the average length of each word.*
35+
- **Space Complexity:** *O(1) - ignoring output space.*
36+
- **Example/Dry Run:**
37+
38+
```plaintext
39+
Example input: ["Hello", "Alaska", "Dad", "Peace"]
40+
41+
"Hello" → uses letters from multiple rows → ✘
42+
"Alaska" → only row 2 → ✔
43+
"Dad" → only row 2 → ✔
44+
"Peace" → multiple rows → ✘
45+
46+
Output: ["Alaska", "Dad"]
47+
```
48+
49+
### 2️⃣ Optimized Approach
50+
51+
- **Explanation:** *Instead of checking characters one by one, convert each row into a set. Then convert the word into a lowercase set and check if it's a subset of any of the three row sets.*
52+
- **Time Complexity:** *O(n * m) - where n is the number of words and m is the average length of the words. Checking issubset is efficient for set comparisons.*
53+
- **Space Complexity:** *O(1) - excluding the space for the output list.*
54+
- **Example/Dry Run:**
55+
56+
```plaintext
57+
Example input: ["Hello", "Alaska", "Dad", "Peace"]
58+
59+
Step 1 → Convert keyboard rows into sets
60+
Step 2 → For each word, convert to lowercase set
61+
Step 3 → Check if set is subset of row1, row2, or row3
62+
63+
Output: ["Alaska", "Dad"]
64+
```
65+
66+
### 3️⃣ Best / Final Optimized Approach (if applicable)
67+
68+
- **Explanation:** *The current solution is optimal for this problem. Using sets makes subset checking straightforward and efficient.*
69+
- **Time Complexity:** *O(n * m)*
70+
- **Space Complexity:** *O(1)*
71+
- **Example/Dry Run:**
72+
73+
```plaintext
74+
Input: ["Type", "Row", "Zzz"]
75+
76+
"Type" → mixed rows → ✘
77+
"Row" → row 1 → ✔
78+
"Zzz" → row 3 → ✔
79+
80+
Output: ["Row", "Zzz"]
81+
```
82+
83+
---
84+
85+
## 📊 Complexity Analysis
86+
87+
| Approach | Time Complexity | Space Complexity |
88+
| ------------- | --------------- | ---------------- |
89+
| Brute Force | O(n * m) | O(1) |
90+
| Optimized | O(n * m) | O(1) |
91+
| Best Approach | O(n * m) | O(1) |
92+
93+
---
94+
95+
## 📉 Optimization Ideas
96+
97+
*You could pre-map each letter to its row number and then verify if all characters in a word belong to the same row number. This might slightly improve runtime in practice, but the set-based method is already clean and efficient.*
98+
99+
---
100+
101+
## 📌 Example Walkthroughs & Dry Runs
102+
103+
104+
```plaintext
105+
Example:
106+
Input: ["Alaska", "Dad", "Peace"]
107+
108+
Process:
109+
1. Alaska → to lower → "alaska" → set("alaska") = {'a', 'l', 's', 'k'} ⊆ row2 → ✔
110+
2. Dad → "dad" → {'d', 'a'} ⊆ row2 → ✔
111+
3. Peace → "peace" → {'p', 'e', 'a', 'c'} ⊄ any row → ✘
112+
113+
Output: ["Alaska", "Dad"]
114+
```
115+
116+
---
117+
118+
## 🔗 Additional Resources
119+
120+
- [Resource 1](https://www.w3schools.com/python/python_sets.asp)
121+
- [Resource 2](https://docs.python.org/3/library/stdtypes.html#set.issubset)
122+
- [Resource 3](https://leetcode.com/problems/keyboard-row/solutions/)
123+
124+
---
125+
126+
Author: Daniel Nallapalli <br>
127+
Date: 16/06/2025
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Note: The returned array must be malloced, assume caller calls free().
3+
*/
4+
bool isInRow(const char* row, const char* word) {
5+
for (int i = 0; word[i]; i++) {
6+
if (!strchr(row, tolower(word[i]))) {
7+
return false;
8+
}
9+
}
10+
return true;
11+
}
12+
13+
char** findWords(char** words, int wordsSize, int* returnSize) {
14+
const char* row1 = "qwertyuiop";
15+
const char* row2 = "asdfghjkl";
16+
const char* row3 = "zxcvbnm";
17+
18+
char** result = (char**)malloc(wordsSize * sizeof(char*));
19+
int count = 0;
20+
21+
for (int i = 0; i < wordsSize; i++) {
22+
char* word = words[i];
23+
if (isInRow(row1, word) || isInRow(row2, word) || isInRow(row3, word)) {
24+
result[count++] = word;
25+
}
26+
}
27+
28+
*returnSize = count;
29+
return result;
30+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution(object):
2+
def findWords(self, words):
3+
"""
4+
:type words: List[str]
5+
:rtype: List[str]
6+
"""
7+
row1 = set("qwertyuiop")
8+
row2 = set("asdfghjkl")
9+
row3 = set("zxcvbnm")
10+
11+
result = []
12+
for word in words:
13+
lower_word = set(word.lower())
14+
if lower_word.issubset(row1) or lower_word.issubset(row2) or lower_word.issubset(row3):
15+
result.append(word)
16+
return result

0 commit comments

Comments
 (0)