一个有关堆的LeetCode问题的复杂度分析
来源:8-7 Leetcode上优先队列相关问题
Genpeng
2018-12-06
波波老师:
您好!
我的问题和LeetCode第692题【前K个高频单词】有关,下面是问题的描述:
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
示例 1:
输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 输出: ["i", "love"] 解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。 注意,按字母顺序 "i" 在 "love" 之前。
示例 2:
输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 输出: ["the", "is", "sunny", "day"] 解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词, 出现次数依次为 4, 3, 2 和 1 次。
注意:
假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
输入的单词均由小写字母组成。
扩展练习:
尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。
我的问题是这样的,这道题可以采用优先队列进行求解(维护一个只有K个元素的最小堆),而我尝试借助桶排序进行求解,但是有一小段代码不知道如何分析时间复杂度,所以向波波老师求助。
代码如下:
/** * This is the solution of No. 692 problem in the LeetCode by using bucket sort, * the website of the problem is as follow: * https://leetcode.com/problems/top-k-frequent-words/ * * @author StrongXGP (xgp1227@gmail.com) * @date 2018/12/05 */ public class Solution4 { public List<String> topKFrequent(String[] words, int k) { // 1. 统计单词的词频 // 时间复杂度为 O(n) Map<String, Integer> wordFreq = new HashMap<>(16); for (String word : words) { wordFreq.put(word, wordFreq.getOrDefault(word, 0) + 1); } // 2. 使用桶排序将单词按照词频进行分组 // 时间复杂度为 O(n) List<String>[] bucket = new List[words.length + 1]; for (String word : wordFreq.keySet()) { int freq = wordFreq.get(word); if (bucket[freq] == null) { bucket[freq] = new ArrayList<>(); } bucket[freq].add(word); } // >>> ??? 此处即为不知道如何进行时间复杂度分析的地方 ??? <<< // 3. 取出 top k 词频的单词(备注:词频相同的单词按照字母顺序排列) List<String> result = new ArrayList<>(); for (int i = words.length; i > 0 && result.size() < k; --i) { if (bucket[i] != null) { if (bucket[i].size() > 1) { Collections.sort(bucket[i]); } result.addAll(bucket[i]); } } return result.subList(0, k); } }
下面这段代码不知道该如何分析时间复杂度。
麻烦老师了。
写回答
1回答
-
这里可以用均摊分析。
最好的情况,显然是每个桶里只有一个元素,此时循环中的复杂度是O(1)的;
但是最坏的情况,某一个桶中有全部元素。里面的排序复杂度是O(nlogn)的。但是,这样的桶最多只可能有一个,摊到循环中,每一次平均摊到是O(logn);
对于其他情况,比如两个桶是n/2,或者三个桶是n/3,或者四个桶是a,b,c,d,但a+b+c+d=n,把其中所有的排序时间加起来,再均摊到每一次循环中,都小于logn
所以这一部分的时间复杂度可以认为是O(nlogn)的:)
继续加油!:)
012018-12-06
相似问题