Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below.
Example 1:
Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]
Note:
- You may use one character in the keyboard more than once.
- You may assume the input string will only contain letters of alphabet.
解法1:
class Solution(object):
def findWords(self, words):
"""
:type words: List[str]
:rtype: List[str]
"""
return [w for w in words if self.is_in_keyboard_row(w)]
def is_in_keyboard_row(self, word):
s1 = set("qwertyuiop")
s2 = set("asdfghjkl")
s3 = set("zxcvbnm")
s = s1
word = word.lower()
if word[0] in s1:
s = s1
elif word[0] in s2:
s = s2
else:
s = s3
i = 1
while i < len(word):
if word[i] not in s:
return False
i += 1
return True
代码重构,像if比较多的可以用查找表做。set可以使用26数组来表示map替代。
解法2:
def findWords(self, words):
line1, line2, line3 = set('qwertyuiop'), set('asdfghjkl'), set('zxcvbnm')
ret = []
for word in words:
w = set(word.lower())
if w.issubset(line1) or w.issubset(line2) or w.issubset(line3):
ret.append(word)
return ret
直接使用python的subset函数。
因为:
s.issubset(t) 测试是否 s 中的每一个元素都在 t 中
解法3:
使用正则表达式
def findWords(self, words):
return filter(re.compile('(?i)([qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*)$').match, words)
解法4:
利用位运算省掉一开始找单词首字母在哪个set:
class Solution {
public:
vector<string> findWords(vector<string>& words) {
vector<int> dict(26);
vector<string> rows = {"QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"};
for (int i = 0; i < rows.size(); i++) {
for (auto c : rows[i]) dict[c-'A'] = 1 << i;
}
vector<string> res;
for (auto w : words) {
int r = 7;
for (char c : w) {
r &= dict[toupper(c)-'A'];
if (r == 0) break;
}
if (r) res.push_back(w);
}
return res;
}
};
标签:set,word,self,words,keyboard,return,leetcode,500,Row From: https://blog.51cto.com/u_11908275/6381145