判断是否在键盘的同一行 Keyboard Row

问题:

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.

American keyboard

Example 1:

Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]

Note:

  1. You may use one character in the keyboard more than once.
  2. 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]);
    }
}

转载于:https://my.oschina.net/liyurong/blog/916004

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值