字符串出现次数的TopK问题

734 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

字符串出现次数的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个元素。

  1. 开始时,我们将字典中的前k个元素加入优先级队列中(默认是小顶堆)。
  2. 如果map中剩余节点的num大于堆顶节点的num,入堆。
  3. 将建立好的堆从后往前输出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]