给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。
示例:
输入: ["Hello", "Alaska", "Dad", "Peace"]
输出: ["Alaska", "Dad"]
注意:
你可以重复使用键盘上同一字符。
你可以假设输入的字符串将只包含字母。
答案:
1public String[] findWords(String[] words) {
2 List<String> result = new ArrayList(words.length);
3 Map<Character, Integer> map = new HashMap<>();
4 String level1 = "qwertyuiopQWERTYUIOP";
5 String level2 = "asdfghjklASDFGHJKL";
6 String level3 = "zxcvbnmZXCVBNM";
7 for (char c : level1.toCharArray()) {
8 map.put(c, 1);
9 }
10 for (char c : level2.toCharArray()) {
11 map.put(c, 2);
12 }
13 for (char c : level3.toCharArray()) {
14 map.put(c, 3);
15 }
16 for (String word : words) {
17 boolean valid = true;
18 int row = map.get(word.charAt(0));
19 for (int i = 1; i < word.length(); i++) {
20 if (row != map.get(word.charAt(i))) {
21 valid = false;
22 break;
23 }
24 }
25 if (valid)
26 result.add(word);
27 }
28 return result.toArray(new String[]{});
29}
解析:
代码很好理解,就不再多说,再来看一种写法
1// zyxwvutsrqponmlkjihgfedcba
2private static final int ROW1 = 0b00000001010110111100000100010000;
3private static final int ROW2 = 0b00000000000001000000111011101001;
4private static final int ROW3 = 0b00000010101000000011000000000110;
5
6public String[] findWords(String[] words) {
7 String[] validWords = new String[words.length];
8 int validWordsFound = 0;
9 int wordLetterIndexes = 0;
10 for (String word : words) {
11 wordLetterIndexes = getLetterIndexes(word);
12 if ((wordLetterIndexes & ROW1) == wordLetterIndexes
13 || (wordLetterIndexes & ROW2) == wordLetterIndexes
14 || (wordLetterIndexes & ROW3) == wordLetterIndexes) {
15 validWords[validWordsFound++] = word;
16 }
17 }
18 return Arrays.copyOf(validWords, validWordsFound);
19}
20
21private static final int getLetterIndexes(String word) {
22 int letters = 0;
23 char c;
24 for (int i = 0; i < word.length(); i++) {
25 c = word.charAt(i);
26 letters |= 1 << ((c < 'a') ? c - 'A' : c - 'a');
27 }
28 return letters;
29}
这里通过位运算的方式进行计算,其中ROW1,ROW2,ROW3表示的是键盘上的字母所在的行,但他并没有和键盘上的顺序进行一一对应。getletterIndexes方法把单词word转化为二进制表示。