问题:
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.
解决:
①使用一个数组来存储keyboard组成的字符串。遍历传入的words数组,将字符串转换为字符数组,判断字符数组中是否全部与数组中第一个字符在同一行中(所有字符都在同一行),若在同一行则将其加入返回数组中,否则不加入。耗时3ms。
public class Solution {
public String[] findWords(String[] words) {
List<String> list = new ArrayList<String>();
String[] keyboard = {"QWERTYUIOPqwertyuiop","ASDFGHJKLasdfghjkl","ZXCVBNMzxcvbnm"};//一行键盘所表示的字符,用数组表示
for(String word : words){
String realWord = word;
char[] tmp = word.toCharArray();//将单词的字符串转换为字符数组
int count = 0;//记录在同一行的字符的数目
for (char t : tmp) {//查看字符数组,看是否所有字符都在同一行
if(keyboard[0].indexOf(tmp[0]) != -1){//若字符数组中第一个字符在第一行,则之后的必须在同一行,否则中断
if (keyboard[0].indexOf(t) == -1) {
break;
}
}else if (keyboard[1].indexOf(tmp[0]) != -1) {
if (keyboard[1].indexOf(t) == -1) {
break;
}
}else if (keyboard[2].indexOf(tmp[0]) != -1) {
if (keyboard[2].indexOf(t) == -1) {
break;
}
}
count ++;
}
if (count == tmp.length) {//整个单词数组的字符都在同一行
list.add(realWord);
}
}
String[] res = new String[list.size()];
for (int i = 0;i < list.size();i ++) {
res[i] = list.get(i);
}
return res;
}
}
class Solution {//2ms
public String[] findWords(String[] words) {
String[] keyboard = {"QWERTYUIOPqwertyuiop","ASDFGHJKLasdfghjkl","ZXCVBNMzxcvbnm"};
List<String> res = new ArrayList<>();
for (String word : words) {
char[] tmp = word.toCharArray();
for (int i = 0;i < keyboard.length ;i ++ ) {
if (keyboard[i].indexOf(tmp[0]) != -1) {
int j = 0;
for (;j < tmp.length ;j ++ ) {
if (keyboard[i].indexOf(tmp[j]) == -1) {
break;
}
}
if(j == tmp.length){
res.add(word);
}
}
}
}
return res.toArray(new String[res.size()]);
}
}
②使用一个标记表明某字符是否在该行,大体思路与上一题一致,耗时3ms.
public class Solution {
public String[] findWords(String[] words) {
char[] row1Chars = new char[] {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'};
char[] row2Chars = new char[] {'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'};
char[] row3Chars = new char[] {'z', 'x', 'c', 'v', 'b', 'n', 'm', 'Z', 'X', 'C', 'V', 'B', 'N', 'M'};
boolean[] row1 = new boolean[256];
boolean[] row2 = new boolean[256];
boolean[] row3 = new boolean[256];
for(int i = 0; i < row1Chars.length; ++i) row1[row1Chars[i]] = true; //用于标记该行中是否包含某字符
for(int i = 0; i < row2Chars.length; ++i) row2[row2Chars[i]] = true;
for(int i = 0; i < row3Chars.length; ++i) row3[row3Chars[i]] = true;
ArrayList<String> res = new ArrayList<String>();
for(int i = 0; i < words.length; ++i) {
boolean found = true;//标记是否在同一行中找到全部字符
String curWord = words[i];//用于存储当前字符串
for(int j = 0; j < curWord.length() && found; ++j) {
if(!row1[curWord.charAt(j)]) found = false;//判断字符串中第J个字符是否在该行
}
if(!found) {
found = true;
for(int j = 0; j < curWord.length() && found; ++j) {
if(!row2[curWord.charAt(j)]) found = false;
}
}
if(!found) {
found = true;
for(int j = 0; j < curWord.length() && found; ++j) {
if(!row3[curWord.charAt(j)]) found = false;
}
}
if(found) res.add(curWord);
}
return res.toArray(new String[0]);//如果指定的数组能容纳该 res,则返回包含此 res 元素的数组。否则,将根据指定数组的运行时类型和此 res 的大小分配一个新数组。这里给的参数的数组长度是0,因此就会返回包含此 res 中所有元素的数组,并且返回数组的类型与指定数组的运行时类型相同。toArray(new Object[0]) 和 toArray() 在功能上是相同的。
}
}
③使用Map存储keyboard内容,键为每个字符,值是它属于哪一行。耗时5ms。
public class Solution {
public String[] findWords(String[] words) {
String[] keyBoard = {"QWERTYUIOPqwertyuiop","ASDFGHJKLasdfghjkl","ZXCVBNMzxcvbnm"};
Map<Character,Integer> map = new HashMap<>();
for (int i = 0;i < keyBoard.length ;i ++ ) {
for (char c : keyBoard[i].toCharArray() ) {//在map中保存所有的字符,值表明所属的行
map.put(c,i);
}
}
List<String> list = new ArrayList<>();
for (String word : words) {
char[] tmp = word.toCharArray();
int index = map.get(tmp[0]);
for (char t : tmp) {
if (map.get(t) != index) {
index = -1;//不需要额外的flag
break;
}
}
if(index != -1) list.add(word);
}
return list.toArray(new String[0]);
}
}