小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
字符串出现次数的TopK问题
问题描述
给定一个字符串数组,再给定整数 k ,请返回出现次数前k名的字符串和对应的次数。返回的答案应该按字符串出现频率由高到低排序。如果不同的字符串有相同出现频率,按字典序排序。
示例:
输入:["a","b","c","b"],2
输出:[["b","2"],["a","1"]]
分析问题
这道题最直观的解法就是遍历字符串数据,将元素放入一个字典中统计出现的次数,然后将字典中的元素按照value排序,如果value相等,再按照key排序,最后返回前k个值就好。
class Solution:
def topKstrings(self , strings , k ):
# write code here
dic={}
#用字典统计每个字符串出现的次数
for s in strings:
if s in dic:
dic[s]=dic[s]+1
else:
dic[s]=1
#返回排序后的前k个元素
return sorted(dic.items(),key=lambda kv:(-kv[1],kv[0]))[0:k]
在统计完每个字符串出现的次数后,我们也可以使用优先级队列来求出topk个元素。
- 开始时,我们将字典中的前k个元素加入优先级队列中(默认是小顶堆)。
- 如果map中剩余节点的num大于堆顶节点的num,入堆。
- 将建立好的堆从后往前输出K个,即是最大的K个元素。
import heapq
class Word:
def __init__(self, word, count):
self.word = word
self.count = count
def __lt__(self, other):
#字符比较的顺序,先按照count进行比较,如果count相同,
#字典序越小,排序越靠前
if self.count != other.count:
return self.count < other.count
else:
return self.word > other.word
class Solution:
def topKstrings(self , strings , k ):
# write code here
dic = {}
# 用字典统计每个字符串出现的次数
for s in strings:
if s in dic:
dic[s] = dic[s] + 1
else:
dic[s] = 1
pq = []
#用小顶堆存储最大的k个数
for word in dic.keys():
heapq.heappush(pq, Word(word, dic[word]))
if len(pq) > k:
heapq.heappop(pq)
#排序,最大的放在首位
pq.sort(reverse=True)
return [[x.word,x.count] for x in pq]