LeetCode刷题记录(第九天)

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.

翻译后:

给定一个单词列表,只返回可在美式键盘的一行上使用字母表输入的单词,如下图所示。


思路:

这道题也还是比较简单的,现在已经把正确率60+的都做完了,嘿嘿。

1、首先,要遍历这个数组拿到每一个元素;

2、然后遍历每一个元素也就是每一个字符串;

3、找到第一个字母在键盘中的位置,如果后面的全在这一行,则把这个字符串加到一个新数组中,不在则继续遍历下一个字符串,直到遍历完集合为止。

以下是我编写的代码:

package com.mianshi.suanfa.KeyboardRow;

/**
 * Created by macbook_xu on 2018/3/29.
 */
public class Solution {
    public static String[] findWords(String[] words) {

        String[] re = new String[1024];

        char[] c1 = {'q','w','e','r','t','y','u','i','o','p','Q','W','E','R','T','Y','U','I','O','P'};
        char[] c2 = {'a','s','d','f','g','h','j','k','l','A','S','D','F','G','H','J','K','L'};
        char[] c3 = {'z','x','c','v','b','n','m','Z','X','C','V','B','N','M'};

        for (String s1 : words){
            for (int i = 0 ; i<s1.length() ; i++){

            }
        }
        return re;

    }
}

看到了别生气。。。。为什么就写了一部分呢?因为里面的代码有思路但是写的时候发现行不通啊,可以一个字母一个字母的去比较记录,但那真的是相当的麻烦,不光代码会麻烦,在运行是时耗上也非常繁琐,所以我知道了,这个题看着简单,但是我还是没有做出来,唉,算法虐我千百遍啊。


但是,很多大神还是很厉害的,并不是说他们写代码写的多厉害,是他们对程序和问题的理解非常的到位,我现在拿到算法题,只能出现一种思路,这样的思路行不通,我就不会了。但是大神们看到题会有不通的思路,一种办法行不通他们会使用其他的方法替代,想要这样,首先需要非常扎实的基础知识,还有经验的积累。这道题让我再次意识到自己的不足,还是先看以下大神的代码吧:

public class Solution {
    public String[] findWords(String[] words) {
        String[] strs = {"QWERTYUIOP","ASDFGHJKL","ZXCVBNM"};
        Map<Character, Integer> map = new HashMap<>();
        for(int i = 0; i<strs.length; i++){
            for(char c: strs[i].toCharArray()){
                map.put(c, i);//put <char, rowIndex> pair into the map
            }
        }
        List<String> res = new LinkedList<>();
        for(String w: words){
            if(w.equals("")) continue;
            int index = map.get(w.toUpperCase().charAt(0));
            for(char c: w.toUpperCase().toCharArray()){
                if(map.get(c)!=index){
                    index = -1; //don't need a boolean flag. 
                    break;
                }
            }
            if(index!=-1) res.add(w);//if index != -1, this is a valid string
        }
        return res.toArray(new String[0]);
    }
}

首先,他把这三行字母放进了一个map中,而且每一行都是一个数组,并且value就是行数;

然后,定义一个list来存放符合题目要求的字符串,遍历传入的数组,取得第一个字母在哪一行,然后遍历这个字符串取它每个字母所在行数,如果后面的字母出现不和首字母所在行数一样的,直接跳出继续下一个字符串遍历,如果后面的都相同,则加入list中。

最后,list转换为数组返回。

看待问题的角度和想法真的很重要,当然还有更厉害的大神,只用一行代码哦,是不是不相信?那就上代码:

public String[] findWords(String[] words) {
    return Stream.of(words).filter(s -> s.toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")).toArray(String[]::new);
}

哇哇哇,看完这个我都佩服的五体投地啊。。。。。虽然没看懂,但是就感觉很牛,哈哈。

这个主要使用了正则表达式,虽然上次整理了部分正则表达式,但现在发现,自己还是太嫩了。

首先这个方法使用了stream,关于stream,大家可以直接百度,因为我也是现学的,就不在这里误人子弟了,用stream筛选出来了匹配正则表达式的单词,然后转化数组返回。具体的细节还没有全部学习明白,大家会的要留言教我哦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值