比较两个对象的大小关系原来可以如此花里胡哨

一,先看一下题目

给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

看完题目你是不是已经有了想法??????
TopK???
NO!!!
(慢慢品)

二,解题思路

1.借助Map统计各个单词的出现次数
2.把键值对组织到一个ArrayList中
3.按照题目要求进行降序排序(出现次数+字典序)

不多说!!!!下面才是重点

三,上代码(看点在这里)

先把统计结果放入一个ArrayList

public List<String> topKFrequent(String[] words,int k){
    //先统计各单词出现次数
    Map<String,Integer> map = new HashMap<>();
    for (String s : words ) {
        int count = map.getOrDefault(s,0);//获取到当前单词出现次数
        map.put(s,count+1);//存入map中
    }
    //把刚才统计到的字符串放到ArrayList中
    //KeySet相当于得到了一个Set,Set中存放的就是所有的key
    ArrayList<String> arrayList = new ArrayList(map.keySet());
 //按照刚才的统计次数,针对ArrayList进行排序

接下来就开始表演了

1.使用集合类Collections自带的sort方法对ArrayList进行排序

注意: sort默认按元素自身大小进行升序排序(String的字典序) 此处我们要按照字符串出现次数降序排序,也就需要比较器自定制比较规则

思考:这里我们用Comparable行不行???

答案:不行 原因:因为我们是针对String进行制定比较规则,要比较就要更改String源码,你能改吗?

所以我们得重新写一个比较器,来指定String什么算大,什么算小

static class MyComparator implements Comparator<String>{
        private Map<String,Integer> map;
public MyComparator(Map<String, Integer> map) {
            this.map = map;
        }

        @Override
        public int compare(String o1, String o2) {
            int count1 =map.get(o1);
            int count2 = map.get(o2);
            if(count1 == count2){
                //String自身实现了Comparable,自带字典序的比较功能
                //CompareTo就是使用String默认的比较规则
                return o1.compareTo(o2);
            }
            return count2-count1;
        }
    }
    public List<String> topKFrequent(String[] words,int k){
    //先统计各单词出现次数
    Map<String,Integer> map = new HashMap<>();
    for (String s : words ) {
        int count = map.getOrDefault(s,0);//获取到当前单词出现次数
        map.put(s,count+1);//存入map中
    }
    //把刚才统计到的字符串放到ArrayList中
    //KeySet相当于得到了一个Set,Set中存放的就是所有的key
    ArrayList<String> arrayList = new  ArrayList(map.keySet());
    Collections.sort(arrayList,new MyComparator(map));
     return arrayList.subList(0,k);
}

2.使用匿名内部类(语法糖)

什么时候用到内部匿名类??
这个类只用一次,用完就丢了

  public List<String> topKFrequent(String[] words,int k){
    //先统计各单词出现次数
    Map<String,Integer> map = new HashMap<>();
    for (String s : words ) {
        int count = map.getOrDefault(s,0);//获取到当前单词出现次数
        map.put(s,count+1);//存入map中
    }
    //把刚才统计到的字符串放到ArrayList中
    //KeySet相当于得到了一个Set,Set中存放的就是所有的key
    ArrayList<String> arrayList = new  ArrayList(map.keySet());
Collections.sort(arrayList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int count1 = map.get(o1);
                int count2 = map.get(o2);
                if(count1 == count2){
                  return  o1.compareTo(o2);
                }
               return count2-count1;
            }
        });
         return arrayList.subList(0,k);
}

3.使用lambda表达式(语法糖)

lambda表达式,本质上就是一个匿名方法

public List<String> topKFrequent(String[] words,int k){
    //先统计各单词出现次数
    Map<String,Integer> map = new HashMap<>();
    for (String s : words ) {
        int count = map.getOrDefault(s,0);//获取到当前单词出现次数
        map.put(s,count+1);//存入map中
    }
    //把刚才统计到的字符串放到ArrayList中
    //KeySet相当于得到了一个Set,Set中存放的就是所有的key
    ArrayList<String> arrayList = new ArrayList(map.keySet());
 Collections.sort(arrayList, (o1, o2) ->{
            int count1 = map.get(o1);
            int count2 = map.get(o2);
            if(count1 == count2){
              return   o1.compareTo(o2);
            }
            return count2-count1;

    });
    return arrayList.subList(0,k);
}

这两颗糖是硬糖,得慢慢品

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值