力扣(LeetCode)键盘行 个人题解

给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。

American keyboard

示例:

输入: ["Hello", "Alaska", "Dad", "Peace"]
输出: ["Alaska", "Dad"]

注意:

  1. 你可以重复使用键盘上同一字符。
  2. 你可以假设输入的字符串将只包含字母。

这题有取巧的思路,就是用按位与的想法,可以判断出是否会出现其他行的字符,就是设置分别设置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;
    }
};
原文地址:https://www.cnblogs.com/axiangcoding/p/10815920.html