文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 map
    • 2.2 树状数组

1. 题目

假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。

请实现数据结构和算法来支持这些操作,也就是说:

  • 实现 track(int x) 方法,每读入一个数字都会调用该方法;

  • 实现 getRankOfNumber(int x) 方法,返回 小于或等于 x 的值的个数。

示例:
输入:
["StreamRank", "getRankOfNumber", "track", "getRankOfNumber"]
[[], [1], [0], [0]]
输出:
[null,0,null,1]提示:
x <= 50000
track 和 getRankOfNumber 方法的调用次数均不超过 2000 次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rank-from-stream-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 类似题目:LeetCode 315. 计算右侧小于当前元素的个数(二叉查找树&二分查找&归并排序逆序数总结)

2.1 map

  • map 存储自己的个数,写入时间复杂度 O(log⁡n)O(\log n)O(logn)
  • 读取秩的时候,从前往后遍历加起来(小于等于x的)O(n)O(n)O(n) 时间复杂度
class StreamRank {map<int,int> m;int count = 0;
public:StreamRank() {}void track(int x) {m[x]++;}int getRankOfNumber(int x) {count = 0;for(auto& mi : m){if(x >= mi.first)count += mi.second;elsebreak;}return count;}
};

108 ms 13.9 MB

  • map 存储前面小于等于它的个数,读取秩的时间复杂度 O(log⁡n)O(\log n)O(logn)
  • 插入数以后,需要更新所有的 map 的 value,时间复杂度 O(n)O(n)O(n)
class StreamRank {map<int,int> m;
public:StreamRank() {}void track(int x) {auto it = m.rbegin();for(; it != m.rend(); ++it){if(it->first > x)it->second++;//有比x大的,他们的value(比它小的个数) +1elsebreak;}if(it == m.rend() || (it != m.rend() && it->first == x))m[x]++; // map遍历到头了,x不存在,或者x存在elsem[x] = it->second + 1;//遍历没到头,x不存在,x 的 value = 前一个value + 自己}int getRankOfNumber(int x) {if(m.empty() || x < m.begin()->first)return 0;if(m.count(x))return m[x];auto end = m.upper_bound(x);end--;return end->second;}
};

120 ms 14 MB


2.2 树状数组

上面解法:在 n 次操作下的时间复杂度为 O(n2)O(n^2)O(n2)

如何优化:请看树状数组,一次查询和修改时间复杂度均为 O(log⁡n)O(\log n)O(logn)

class StreamRank {vector<int> v;int N = 50002;
public:StreamRank() {v = vector<int>(N);}void track(int x) {update(x+1, 1);}int getRankOfNumber(int x) {return query(x+1);}//-----树状数组-------int lowbit(int x){return x&(-x);}void update(int i, int delta){for( ; i < N; i += lowbit(i))v[i] += delta;}int query(int i){int sum = 0;for( ; i > 0; i -= lowbit(i))sum += v[i];return sum;}
};

44 ms 20.6 MB

程序员面试金典 - 面试题 10.10. 数字流的秩(map/树状数组)相关推荐

  1. 程序员面试金典 - 面试题 16.10. 生存人数(自定义优先队列)

    文章目录 1. 题目 2. 解题 2.1 优先队列 2.2 双指针 1. 题目 给定N个人的出生年份和死亡年份,第i个人的出生年份为 birth[i],死亡年份为 death[i],实现一个方法以计算 ...

  2. 程序员面试金典 - 面试题 08.10. 颜色填充(BFS/DFS)

    1. 题目 颜色填充.编写函数,实现许多图片编辑软件都支持的"颜色填充"功能. 给定一个屏幕(以二维数组表示,元素为颜色值).一个点和一个新的颜色值,将新颜色值填入这个点的周围区域 ...

  3. 程序员面试金典 - 面试题 04.10. 检查子树(双重递归)

    1. 题目 检查子树.你有两棵非常大的二叉树:T1,有几万个节点:T2,有几万个节点. 设计一个算法,判断 T2 是否为 T1 的子树. 如果 T1 有这么一个节点 n,其子树与 T2 一模一样,则 ...

  4. 程序员面试金典 - 面试题 17.17. 多次搜索(Trie树)

    文章目录 1. 题目 2. 解题 2.1 暴力超时 2.2 Trie树 1. 题目 给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串, ...

  5. 程序员面试金典 - 面试题 17.13. 恢复空格(DP+Trie树)

    文章目录 1. 题目 2. 解题 2.1 动态规划 2.2 Trie树 1. 题目 哦,不!你不小心把一个长篇文章中的空格.标点都删掉了,并且大写也弄成了小写. 像句子"I reset th ...

  6. 程序员面试金典 - 面试题 08.13. 堆箱子(DP)

    1. 题目 堆箱子.给你一堆n个箱子,箱子宽 wi.深 di.高 hi. 箱子不能翻转,将箱子堆起来时,下面箱子的宽度.高度和深度必须大于上面的箱子. 实现一种方法,搭出最高的一堆箱子.箱堆的高度为每 ...

  7. 程序员面试金典 - 面试题 17.08. 马戏团人塔(最长上升子序 DP/二分查找)

    文章目录 1. 题目 2. 解题 2.1 超时解 2.2 二分查找 1. 题目 有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上.出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一 ...

  8. 程序员面试金典 - 面试题 10.03. 搜索旋转数组

    题目难度: 中等 原题链接 今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 搜索旋转数组.给定一个排序后的数组 ...

  9. 程序员面试金典 - 面试题 10.11. 峰与谷

    题目难度: 中等 原题链接 今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 在一个整数数组中,"峰& ...

  10. 程序员面试金典 - 面试题 17.07. 婴儿名字

    题目难度: 中等 原题链接 今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 每年,政府都会公布一万个最常见的婴 ...

最新文章

  1. linux 禁用ipv6 方法
  2. Swoole同步/异步/阻塞/非阻塞的理解
  3. mysql复杂操作,.Net Core+mySqlSugar的一些稍复杂操作
  4. 【数据结构】之算法和算法评价
  5. 转贴:Hyper-V的几款免费管理工具
  6. 放松时刻——C#分割字符串
  7. pmbok第七版_PMBOK第七版要来了!都有哪些变化?你准备好了么?
  8. 使用printf函数输出其ascii。_输入一个N*N的矩阵,将其转置后输出。要求:不得使用任何数组(就地逆置)。...
  9. Linux 数据处理
  10. SVN 冲突文件快速解决方法
  11. 记一次进销存软件的破解(补充)
  12. eova利用js默认初始查询值查询
  13. 机器学习的四种学习方法
  14. 一文带你彻底了解电子灌封(灌胶)工艺技术
  15. Center Loss的Pytorch实现
  16. QT篇之QT布局与设计师
  17. 机器学习之Pandas教程(上)
  18. 若泽数据公开课-JVM01
  19. 并查集解决朋友圈问题
  20. 扫描软件Nessus官网下载地址和高级扫描使用方法

热门文章

  1. Random Forest算法简介
  2. canny算子的理论分析
  3. java实现控件绑定数据源_控件(三)——TreeView控件以XmlDataSource控件为数据源实现简单的绑定...
  4. mysql备份到带库_RMAN备份恢复——备份到带库的性能
  5. Web页面在桌面上显示的后台基本步骤
  6. 2017.10.25水题大作战题解
  7. Java GridBagLayout 简单使用
  8. ubuntu14.04 64bit主机下面安装android的NDK开发环境
  9. PostgreSQL体系架构
  10. 优雅地用宏实现环形缓冲区