[刷题]Top K Frequent Words

本文探讨了在给定字符串数组中找出出现频率最高的前K个单词的问题,并提供了两种不同的解决方案。第一种方法由于时间复杂度过高导致超时,第二种方法通过使用优先队列和自定义比较器实现了更高效的O(n log k)时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[LintCode]Top K Frequent Words

Version 1 失败

public class Solution {
    /**
     * @param words an array of string
     * @param k an integer
     * @return an array of string
     */
    public String[] topKFrequentWords(String[] words, int k) {
        // 2016-03-09  Time Limit Exceeded
        // 时间O(nk) 空间O(n)    
        // n是words数组长度
        if (words == null || words.length < 1 || k <= 0) {
            return new String[0];
        }
        HashMap<String, Integer> map = new HashMap<>();
        // 遍历words,计算每一个词出现的次数
        for (String word : words) {
            if (word == null) {
                continue;
            }
            if (!map.containsKey(word)) {
                map.put(word, 1);
            } else {
                map.put(word, map.get(word) + 1);
            }
        }
        
        // 下面代码的时间效率太低 O(nk)
        String[] rst = new String[k];
        int max = 0;
        for (int i = 0; i < k; i++) {
            for (String each : map.keySet()) {
                if (map.get(each) > max) {
                    max = map.get(each);
                    rst[i] = each;
                }
                if (map.get(each) == max && leftIsSmaller(each, rst[i])) {
                    rst[i] = each;
                }
            }
            map.remove(rst[i]);
            max = 0;
        }
        return rst;
    }
    
    /**
     * 比较两个字符串的大小
     */
    private boolean leftIsSmaller(String left, String right) {
        int length = Math.min(left.length(), right.length());
        for (int i = 0; i < length; i++) {
            if (left.charAt(i) > right.charAt(i)) {
                return false;
            } 
            if (left.charAt(i) < right.charAt(i)) {
                return true;
            }
        }
        if (left.length() < right.length()) {
            return true;
        } else {
            return false;
        }
    }
}

Version 2

class Pair {
    public String name;
    public int value;
    
    public Pair(String name, int value) {
        this.name = name;
        this.value = value;
    }
}

public class Solution {
    /**
     * @param words an array of string
     * @param k an integer
     * @return an array of string
     */
    
    // 定义比较器 
    Comparator<Pair> comparator = new Comparator<Pair>() {
        public int compare(Pair left, Pair right) {
            if (left.value != right.value) {
                return left.value - right.value;
            } else {
                // return left.name.compareTo(right.name);
                return right.name.compareTo(left.name);
            }
        }
    };
    
    public String[] topKFrequentWords(String[] words, int k) {
        // 2016-3-14 O(nlogk) time and O(n) space
        if (words == null || words.length == 0 || k <= 0) {
            return new String[0];
        }
        if (words.length < k) {
            return null;
        }
        
        // O(n) time
        HashMap<String, Integer> map = new HashMap<>();
        for (String word : words) {
            if (!map.containsKey(word)) {
                map.put(word, 1);
            } else {
                map.put(word, map.get(word) + 1);
            }
        }
        
        // 队列的容量是k    O(nlogk) time
        PriorityQueue<Pair> queue = new PriorityQueue<Pair>(k, comparator);
        for (String key : map.keySet()) {
            Pair newPair = new Pair(key, map.get(key));
            if (queue.size() < k) {
                queue.add(new Pair(key, map.get(key)));
            } else if (comparator.compare(queue.peek(), newPair) < 0) {
                queue.poll();
                queue.add(new Pair(key, map.get(key)));
            }
        }
        
        // O(klogk) time
        String[] rst = new String[k];
        for (int i = k - 1; i >= 0; i--) {
            rst[i] = queue.poll().name;
        }
        return rst;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值