news 2026/4/16 6:23:46

LeetCode 2080 区间频率查询详解(哈希表 + 二分法)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 2080 区间频率查询详解(哈希表 + 二分法)

深度解析:空间换时间的艺术 —— 从区间频率查询看哈希与二分

在处理大规模数据查询时,性能优化是核心。LeetCode 2080 题《区间内查询数字的频率》是一个绝佳的案例。本文将通过“哈希表预处理”与“二分查找”两大维度,带你领略现代 C++ 的解题美学。

一、 哈希表:构建高效的“档案库”

在本题中,如果我们每次查询都遍历区间,时间复杂度是 O(N),面对 10^5 级别的查询必然超时。我们的策略是构建一个 unordered_map<int, vector>。

1. 结构深度解析

这个结构可以理解为一个“分类索引”:

  • Key (键):数组中出现的具体数值(如 33)。
  • Value (值):一个升序排列的 vector,记录了该数值在原数组中出现的所有下标(如 [1, 3, 5])。

2. 增删改查的实战用法

在 C++ 中,unordered_map 是基于哈希表实现的,其平均操作效率为 O(1):

  • 增/改:

    pos[val].push_back(index); // 若 val 不存在,会自动创建一个空的 vector 并添加 index
  • 查(标准定式):
    为了避免不必要的插入(副作用),推荐使用 find() 配合 end() 进行检查:

    auto it = pos.find(target); if (it != pos.end()) { // 找到了,it->second 就是我们要的下标 vector }
  • 删:

pos.erase(val); // 即可瞬间根据键删除对应的内容。

3. 性能关键

在查询函数中,你会看到这样的代码:

auto& a = it->second;
  • 为什么要加 &?
  • 如果不加 &,程序会把整个 vector 拷贝一遍。加上 & 后,a 仅仅是原哈希表中 vector 的一个别名,没有任何数据复制。在处理海量数据时,这一个字符之差就是 TLE(超时)与 AC(通过)的分水岭。

二、 二分查找

有了有序的下标数组后,核心任务就是:在有序数组中,统计有多少个下标落在 [left, right] 之间。此时,std::lower_bound 和 std::upper_bound 就派上用场了。

1. lower_bound:定位左边界

  • 功能:在有序序列中找到第一个 大于等于 (>=) 给定值的元素位置。
  • 应用:lower_bound(a, left) 帮我们找到第一个落在区间内的有效下标位置。

2. upper_bound:定位右边界

  • 功能:在有序序列中找到第一个 严格大于 (>) 给定值的元素位置。
  • 应用:upper_bound(a, right) 帮我们找到第一个“越出”右边界的位置。

3. 核心计算公式

两个迭代器相减,即是该数值在区间内出现的次数:

return ranges::upper_bound(a, right) - ranges::lower_bound(a, left);

三、 完整实现代码 (C++20 风格)

class RangeFreqQuery { // 哈希表:数值 -> 有序下标数组 unordered_map<int, vector<int>> pos; public: RangeFreqQuery(vector<int>& arr) { // 预处理:O(N) 建立索引 for (int i = 0; i < arr.size(); ++i) { pos[arr[i]].push_back(i); // 顺序遍历确保了下标序列是天然升序的 } } int query(int left, int right, int value) { // 使用定式查找,避免副作用 auto it = pos.find(value); if (it == pos.end()) return 0; // 数值根本没出现过 // 获取引用 (&),拒绝大规模拷贝 const auto& a = it->second; // 二分查找:O(log M) auto L = std::ranges::lower_bound(a, left); auto R = std::ranges::upper_bound(a, right); return R - L; // 迭代器相减得到元素个数 } };

四、 总结

本题是典型的“空间换时间”策略。我们通过哈希表将乱序数组按值分类,再通过二分法将线性搜索优化为对数搜索。

关键点回顾:

  1. 哈希表:掌握 find 定式,通过 Key 瞬间定位数据。
  2. 引用 &:它是 C++ 程序员的性能尊严,拒绝无谓拷贝。
  3. 二分边界:记住 lower 是第一个“不小于”,upper 是第一个“大于”。

相关链接:https://github.com/0voice

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:18:07

基于大数据的国内篮球联赛数据分析与可视化系统的设计与实现

国内篮球联赛数据分析与可视化的研究背景 近年来&#xff0c;国内篮球联赛&#xff08;如CBA&#xff09;的竞技水平和商业价值显著提升&#xff0c;赛事数据量呈现爆炸式增长。传统的统计方法已难以应对海量数据的处理需求&#xff0c;而大数据技术的引入为篮球数据分析提供了…

作者头像 李华
网站建设 2026/4/16 10:22:04

轻便型国产DVL推荐,怎么选购是关键,偶信科技教你怎么选?

在水下探测、海洋科考、水下装备导航等场景中&#xff0c;DVL&#xff08;多普勒计程仪&#xff09;早已成为不可或缺的核心设备。随着国产技术的崛起&#xff0c;轻便型DVL凭借灵活适配、易于集成的优势&#xff0c;逐渐取代传统笨重设备成为市场主流。但面对五花八门的产品&a…

作者头像 李华
网站建设 2026/4/16 10:16:49

Spring Boot集成JWT Token实现认证授权完整实践

在前后端分离架构中&#xff0c;认证授权是保障系统安全的核心环节。JWT&#xff08;JSON Web Token&#xff09;凭借其无状态、轻量级、可跨域等优势&#xff0c;成为当前前后端分离项目中主流的认证方案。本文将基于完整的Spring Boot项目代码&#xff0c;详细拆解如何集成JW…

作者头像 李华
网站建设 2026/4/16 10:22:16

Amphenol LTW 防水线缆 IP67/IP68 结构解析

在工业自动化、户外设备、LED 照明以及传感器系统中&#xff0c;防水线缆组件是保障系统稳定运行的重要基础件。其中&#xff0c;Amphenol LTW 作为专注于防水连接技术的品牌&#xff0c;其防水线缆在 IP67、IP68 等等级应用中具有较高的工程参考价值。 本文从工程应用角度出发…

作者头像 李华
网站建设 2026/4/16 10:22:02

WinCC报表功能大揭秘,轻松上手无门槛

wincc报表 功能如下&#xff1a; 日报表&#xff1a;每日24点数据&#xff0c;如果设置的是累计值&#xff0c;计算每小时的差值&#xff0c;和最终汇总一日总累计 月报表&#xff1a;每日0点数据显示&#xff0c;如果设置的是累计值&#xff0c;计算每日的差值&#xff0c;和最…

作者头像 李华