【问题标题】:What is the time complexity of getting the max key of a std::map in C++?在 C++ 中获取 std::map 的最大键的时间复杂度是多少?
【发布时间】:2023-03-26 19:08:01
【问题描述】:

我试图在 std::map 中找到最大值,这将是树中的最后一个节点(因为 std::map 键已排序)。

Cppref 说std::map.end() 是常数时间。但是要得到最大的key,我必须得到这个迭代器的前一个值,即*std::prev(std::map.end())

该操作的时间复杂度是多少?

我知道这应该相当于--std::map.end(),但我也不知道该操作的成本。

【问题讨论】:

  • 试试std::map::rbegin()
  • @PaulMcKenzie 试试答案部分:P
  • 被太多答案打败了。哦,好吧。
  • 嗯@PaulMcKenzie 我回答了您发表评论的时间!我先回答,所以你可以做到! ;) 下一次,使用答案部分。 :)

标签: c++ data-structures stl std


【解决方案1】:

改用std::map::rbegin(),其中:

返回一个反向迭代器,指向容器中的最后一个元素(即它的反向开始)。

和:

复杂性

常数。

最后一个词在你耳中听起来应该像音乐。


std::prev(std::map.end()) 的复杂度是 constant


而且,你对等价的理解是错误的。

来自std::prev 备注:

虽然表达式--c.end()经常可以编译,但不是 保证这样做:c.end() 是一个右值表达式,并且有 没有迭代器要求指定右值的递减是 保证工作。特别是,当迭代器被实现为 指针,--c.end() 不会 编译,而std::prev(c.end()) 可以。

【讨论】:

  • 谢谢,这确实有效,但我必须承认我仍然很好奇:我如何找出std::prev(std::map.end()) 的时间复杂度?
  • 更新了@DunPeal,此外,您问题的最后一部分表明您并不完全理解等价性。
  • @DunPeal how would I find out the time complexity of ... 标准函数复杂性保证的权威信息来源是标准文档。还有一些非官方网站以更方便的格式提供相同的信息。
【解决方案2】:

Advancing in any direction is linear in the number of advances(在你的情况下是 one,所以我们可以称之为恒定时间),但你不需要这样做。只需使用rbegin(),它是最后一个元素的迭代器。

std::prev not 等同于 --std::map.end(),后者根本不能保证做任何有用的事情。请参阅std::prev 文档。

【讨论】:

  • 如果我在不满足`BidirectionalIterator`的迭代器上调用它怎么办?编译错误?
  • @DunPeal 试试看!使用rbegin() 的另一个原因。
【解决方案3】:

但是要得到最大的key,我必须得到这个迭代器之前的值,即*std::prev(std::map.end())

该操作的时间复杂度是多少?

std::map.endstd::prev(a_std_map_iterator)std::map::iterator::operator* 都是常量操作。因此,该表达式作为一个整体是恒定的。

请注意,std::prev 的复杂度在第二个参数n 方面最多保证是线性的,默认为1。当n 为常数时,std::prev 整体为常数。

【讨论】:

  • @LightnessRacesinOrbit 确实如此。恒定,但不是最佳的。
猜你喜欢
  • 1970-01-01
  • 2012-07-31
  • 2020-10-13
  • 2020-07-15
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多