Leetcode 692

5 篇文章 0 订阅
1 篇文章 0 订阅

求出现频率最多的k个单词

 

1、使用优先队列解法

    public List<String> topKFrequent(String[] words, int k) {
        List<String> res = new ArrayList<>();
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }

        PriorityQueue<Map.Entry<String, Integer>> q = new PriorityQueue<>(
                (o1, o2) -> {
                    if (o1.getValue() == o2.getValue()) return o2.getKey().compareTo(o1.getKey());
                    return Integer.compare(o1.getValue(), o2.getValue());
                }
        );
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            q.offer(entry);
            if (q.size() > k) q.poll();
        }
        while(!q.isEmpty()) res.add(0, q.poll().getKey());
        return res;
    }

2、bucket&trie排序(值得学习)

    //https://leetcode.com/problems/top-k-frequent-words/discuss/108399/Java-O(n)-solution-using-HashMap-BucketSort-and-Trie-22ms-Beat-81
    public List<String> topKFrequent(String[] words, int k) {
        List<String> res = new ArrayList<>();
        //统计单词出现个数
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }

        //建桶
        TrieBucket[] count = new TrieBucket[words.length + 1];

        for (String word : map.keySet()) {
            int freq = map.get(word);
            if (count[freq] == null) {
                count[freq] = new TrieBucket();
            }
            add(count[freq], word);
        }
        for (int f = count.length - 1; res.size() < k && f > 0; f--) {
            if (count[f] == null) continue;
            get(count[f], res, k);
        }
        return res;

    }

    private void get(TrieBucket root, List<String> res, int k) {
        if (root == null) return;
        if (root.word != null) res.add(root.word);
        if (res.size() == k) return;
        for (int i = 0; i < 26; i++) {
            if (root.next[i] != null) {
                get(root.next[i], res, k);
            }
        }
    }

    private void add(TrieBucket root, String word) {
        TrieBucket cur = root;
        for (char ch : word.toCharArray()) {
            if (cur.next[ch - 'a'] == null) {
                cur.next[ch - 'a'] = new TrieBucket();
            }
            cur = cur.next[ch - 'a'];
        }
        cur.word = word;
    }

    class TrieBucket {
        TrieBucket[] next;
        String word;

        public TrieBucket() {
            this.next = new TrieBucket[26];
            this.word = null;
        }
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值