题目链接: 键盘行
有关题目
给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。
键盘如下图所示。
示例 1:
输入:words = ["Hello","Alaska","Dad","Peace"]
输出:["Alaska","Dad"]
示例 2:
输入:words = ["omk"]
输出:[]
示例 3:
输入:words = ["adsdf","sfd"]
输出:["adsdf","sfd"]
提示:
1 <= words.length <= 20
1 <= words[i].length <= 100
words[i] 由英文字母(小写和大写字母)组成
题解
法一:哈希表 + 遍历
参考微扰理论
class Solution {
public:
const string one = "qwertyuiopQWERTYUIOP";
const string two = "asdfghjklASDFGHJKL";
const string three = "zxcvbnmZXCVBNM";
unordered_map<char, int> mp1, mp2, mp3;
vector<string> findWords(vector<string>& words) {
for (auto &c : one)
mp1[c]++;
for (auto &c : two)
mp2[c]++;
for (auto &c : three)
mp3[c]++;
vector<string> ans;
for (auto &word : words)
{
bool b1 = true;
bool b2 = true;
bool b3 = true;
for (auto &c : word)
{
b1 &= mp1[c];
b2 &= mp2[c];
b3 &= mp3[c];
}
if (b1 || b2 || b3) ans.push_back(word);
}
return ans;
}
};
时间复杂度:O(L + 2 * C),L为words的字符串的总长度,C为英文字母个数,本题为26
空间复杂度:O(2 * C ),C为英文字母个数,本题为26
法二:计数 + 遍历
参考官方题解评论区下大大落鱼
class Solution {
public:
const string s1 = "qwertyuiop";
const string s2 = "asdfghjkl";
const string s3 = "zxcvbnm";
vector<string> findWords(vector<string>& words) {
vector<string> ans;
for (auto &word : words)
{
int cnt1 = 0;
int cnt2 = 0;
int cnt3 = 0;
int len = word.size();
for (auto &c : word)
{
if (s1.find(tolower(c), 0) != -1) cnt1++;
if (s2.find(tolower(c), 0) != -1) cnt2++;
if (s3.find(tolower(c), 0) != -1) cnt3++;
}
if (cnt1 == len || cnt2 == len || cnt3 == len) ans.push_back(word);
}
return ans;
}
};
时间复杂度:O(L + C),L为words的字符串的总长度,C为英文字母个数,本题为26
空间复杂度:O(C ),C为英文字母个数,本题为26
法三:预处理 + 遍历
参考官方题解
思路
为每一个字母标记好行号,然后检查每个字符串中所有字母是否都为同一个行号
class Solution {
public:
vector<string> findWords(vector<string>& words) {
string tab = "12210111011122000010020202";
vector<string> ans;
for (auto &word : words)
{
bool flag = true;
char idx = tab[tolower(word[0]) - 'a'];
for (int i = 1; i < word.size(); i++)
{
if (tab[tolower(word[i]) - 'a'] != idx)
{
flag = false;
break;
}
}
if (flag)
ans.push_back(word);
}
return ans;
}
};