力扣(LeetCode)键盘行 个人题解
给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。
示例:
输入: ["Hello", "Alaska", "Dad", "Peace"] 输出: ["Alaska", "Dad"]
注意:
- 你可以重复使用键盘上同一字符。
- 你可以假设输入的字符串将只包含字母。
这题有取巧的思路,就是用按位与的想法,可以判断出是否会出现其他行的字符,就是设置分别设置1,2,4三种对应三个行,相同的行按位与,如果不同行,相与必为0,就能判断成功了。
由于不太熟练C++的一些操作,故不表,可以参考以下摘抄自评论区的代码:
class Solution { public: vector<string> findWords(vector<string>& words) { vector<string> ans; for (string &w : words) { uint8_t byte = 7; for (char ch : w) { byte &= ht[tolower(ch) - 'a']; if (!byte) { break; } } if (byte) { ans.push_back(w); } } return ans; } private: vector<uint8_t> ht = {2, 4, 4, 2, 1, 2, 2, 2, 1, 2, 2, 2, 4, 4, 1, 1, 1, 1, 2, 1, 1, 4, 1, 4, 1, 4}; };
正常做法就是将设置一个int数组存放每个字母对应的键盘行行数,然后逐一判断。这里要吐槽一下,JAVA用多了,思维惯性想用map来做键值查找,百度来百度去,发现在C++里面太难用了,到最后还是使用数组来替代了。好在字母量不大可以胜任工作。代码如下:
class Solution { public: vector<string> findWords(vector<string>& words) { int fits[26]; fill(fits,fits+26,-1); string letters[3]= {"qwertyuiop","asdfghjkl","zxcvbnm"}; for (int i=0; i<3; i++) { for (char c : letters[i]) { fits[c-'a'] = i; } } vector<string> ans; for (string word : words) { bool mark = true; int rowmark = fits[tolower(word[0])-'a']; for (char c : word) { if (fits[tolower(c)-'a']!=rowmark) { mark = false; break; } } if (mark) { ans.push_back(word); } } return ans; } };