假设我有一个STL set <int> s
和一个int x
,我如何计算s
中小于x
的元素数?
我正在寻找一个O(log n)
(或类似的;任何比O(n)
解决方案更合理的东西;
我已经知道std::distance(s.begin(), s.lower_bound(x))
,但我认为这是O(n)
,因为set
不是随机访问。
答案 0 :(得分:15)
您需要的是“订单统计树”。它本质上是一个增强(二叉搜索)树,它支持附加操作rank(x)
,它为您提供具有更少或相等键的元素数量作为元素x
。第14章在Cormen,Leiserson,Rivest,Stein; “算法简介”应该为您提供算法背景。
web还有一些实现。
答案 1 :(得分:7)
我认为这不可行。您的STL集是基于树的结构,因此即使仅检查元素的存在也是O(log n)。树的节点不会在任何字段中存储它们的子分支的大小(据我所知),因此计算具有某些属性的节点所需的操作数量不能直接来自用于构建树的规则比这些节点的数量。由于您事先并不知道有多少节点的值小于x,因此最坏情况下的性能是所有节点都小于x时,这意味着O(n)最坏情况复杂度。即使值x在树中,您需要O(log n)操作来查找该节点,但是然后需要访问其所有左下降以便对它们进行计数,因此复杂性取决于匹配节点的数量O( n)在最坏的情况下。也许在树的节点中有额外的数据,可以做得更好。
答案 2 :(得分:6)
作为我的评论的后续跟踪:使用红黑二进制搜索树(而不是集合),如果每个节点存储以该节点为根的节点数(每次插入/删除节点时更新),那么您可以得到“节点数大于/小于X”的统计数据非常快。