整数输入流中先前遇到的较小元素的计数
Count of previously smaller elements encountered in an input stream of integers?
给定一个从1到10^5(非重复)的数字输入流,我们需要能够在每个点上告诉之前遇到过多少比这个小的数字。
我尝试在c++中使用集合来维护已经遇到的元素,然后在集合上取当前数字的upper_bound
。但是upper_bound
给了我元素的迭代器,然后我必须再次遍历集合或者使用std::distance
,它在时间上也是线性的。
为了更有效地完成这个任务,我可以维护一些其他的数据结构或遵循一些其他的算法吗?
EDIT:找到一个关于分域树的老问题,在这里很有帮助。顺便说一句,我现在已经解决了这个问题,使用段树从@doynax评论中获得提示。
如何使用二进制索引树来计算小于索引值的元素数量?
无论你使用的是哪种容器,最好将它们作为排序集输入,这样在任何时候我们都可以获得元素索引或迭代器,从而知道在它之前有多少元素。
您需要实现自己的二叉搜索树算法。每个节点应存储两个计数器,其中包含其子节点的总数。
插入二叉树需要O(log n)
。在插入期间,该新元素的所有父元素的计数器都应该增加O(log n)
。
可从存储计数器O(log n)
中导出小于新元素的元素个数。
总运行时间O(n log n)
.
在每个步骤中保持表的排序。使用二分搜索。在每一点上,当你搜索输入流给你的数字时,二分查找会找到下一个最大的数,或者下一个最小的数。使用比较,您可以找到当前输入的索引,其索引将是小于当前输入的数字。该算法耗时O(n^2)
如果使用插入排序将每个数字存储到链表中会怎么样?然后,当找到新元素在列表中的位置时,可以计算比新元素小的元素的数量。
这取决于您是否想要使用std
。在特定情况下, std
的某些部分是低效的。(例如,std::vector
在某些情况下可能被认为是低效的,因为发生了大量的动态分配。)这是一个具体情况具体分析的问题。
一种可能的解决方案是使用跳跃表(相对于链表),因为将元素插入跳跃表比插入数组更容易、更有效。
必须使用跳跃表方法,因此可以使用二分查找来插入每个新元素。(不能在普通链表中使用二分查找。)如果使用累加器跟踪长度,则返回较大元素的个数将像length-index
一样简单。
使用这种方法的另一个可能的好处是,std::set.insert()
在没有提示的情况下已经具有log(n)的效率,因此效率已经存在问题。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- 编译包含字符串的代码时遇到问题
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何在C++向量中奇数元素前面加上值-1,我在使用insert函数时遇到了问题
- 当我向 vector<int *> 添加元素时,我遇到了一些问题
- 循环,直到没有遇到 std::vector 的任何元素
- C++释放矢量元素占用的内存时遇到的麻烦
- 当我编译并即将推动元素时,我会遇到细分错误
- 删除元素时使用 STL 映射的迭代器时遇到问题
- 将元素添加到遇到的结构数组C++"error no match for ‘operator=’"
- 整数输入流中先前遇到的较小元素的计数
- 将元素添加到字符串向量时遇到问题