如何查询最热门的查询串?

作者: Java面试

题目描述

搜索引擎会通过日志文件把用户每次检索使用的所有查询串都记录下来,每个查询串的长度不超过 255 字节。

假设目前有 1000w 个记录(这些查询串的重复度比较高,虽然总数是 1000w,但如果除去重复后,则不超过 300w 个)。请统计最热门的 10 个查询串,要求使用的内存不能超过 1G。(一个查询串的重复度越高,说明查询它的用户越多,也就越热门。)

解答思路

每个查询串最长为 255B,1000w 个串需要占用 约 2.55G 内存,因此,我们无法将所有字符串全部读入到内存中处理。

方法一:分治法

分治法依然是一个非常实用的方法。

划分为多个小文件,保证单个小文件中的字符串能被直接加载到内存中处理,然后求出每个文件中出现次数最多的 10 个字符串;最后通过一个小顶堆统计出所有文件中出现最多的 10 个字符串。

方法可行,但不是最好,下面介绍其他方法。

方法二:HashMap 法

虽然字符串总数比较多,但去重后不超过 300w,因此,可以考虑把所有字符串及出现次数保存在一个 HashMap 中,所占用的空间为 300w*(255+4)≈777M(其中,4 表示整数占用的 4 个字节)。由此可见,1G 的内存空间完全够用。 思路如下

首先,遍历字符串,若不在 map 中,直接存入 map,value 记为 1;若在 map 中,则把对应的 value 加 1,这一步时间复杂度 O(N)

接着遍历 map,构建一个 10 个元素的小顶堆,若遍历到的字符串的出现次数大于堆顶字符串的出现次数,则进行替换,并将堆调整为小顶堆。

遍历结束后,堆中 10 个字符串就是出现次数最多的字符串。这一步时间复杂度 O(Nlog10)

方法三:前缀树法

方法二使用了 HashMap 来统计次数,当这些字符串有大量相同前缀时,可以考虑使用前缀树来统计字符串出现的次数,树的结点保存字符串出现次数,0 表示没有出现。 思路如下

在遍历字符串时,在前缀树中查找,如果找到,则把结点中保存的字符串次数加 1,否则为这个字符串构建新结点,构建完成后把叶子结点中字符串的出现次数置为 1。

最后依然使用小顶堆来对字符串的出现次数进行排序。

方法总结

前缀树经常被用来统计字符串的出现次数。它的另外一个大的用途是字符串查找,判断是否有重复的字符串等。

更多推荐

更多
  • Docker从入门到实践-底层实现-命名空间 命名空间,pid 命名空间,net 命名空间,ipc 命名空间,mnt 命名空间,uts 命名空间,user 命名空间,保证了容器之间彼此互不影响。 pid 命名空间 --------------------------- 不同用
  • Docker从入门到实践-底层实现-基本架构 基本架构,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 `socket` 或者 `RESTful API` 来进行通信。 ![Docker 基本架构](https://static.oom
  • Docker从入门到实践-底层实现-控制组 控制组,,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。 控制组技术最早是由 Google 的程序员在 2006 年提出,Linux 内核自 2.6.24 开始支
  • Docker从入门到实践-底层实现-容器格式 容器格式,er](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和
  • Docker从入门到实践-底层实现-网络 Docker 网络实现,基本原理,创建网络参数,网络配置细节,悉了解这两部分的基本概念再阅读本章。 基本原理 ----------------------- 首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收
  • Docker从入门到实践-底层实现-联合文件系统 联合文件系统,并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual file
  • Docker从入门到实践-底层实现 底层实现,文件系统(Union file systems)和容器格式(Container format)。 们知道,传统的虚拟机通过在宿主主机中运行 hypervisor 来模拟一整套完整的硬件环境提供给虚拟机的操作系统。虚拟机系统看
  • Docker从入门到实践-Swarm mode-部署服务 部署服务,新建服务,查看服务,服务伸缩,删除服务,AME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS * pjfzd39buzlt nginx.1 nginx:1.13.
  • Docker从入门到实践-Swarm mode-创建 Swarm 集群 创建 Swarm 集群,初始化集群,增加工作节点,查看集群,有了一个管理节点,下面们继续创建两个 Docker 主机作为工作节点,并加入到集群中。 ``` * $ docker-machine create -d virt
  • Docker从入门到实践-Swarm mode-管理配置信息 在 Swarm 集群中管理配置数据,创建 config,查看 config,创建 redis 服务,----- 新建 `redis.conf` 文件 ``` * port 6380 ``` 此项配置 Redis
  • 近期文章

    更多
    文章目录

      推荐作者

      更多