实现弹出最常添加的项目的堆栈
Implement the stack that pops the most frequently added item
我被要求实现一个堆栈,该堆栈弹出面试中最常添加的项目。我给了他以下答案,但他对解决方案不满意。
class stack
{
// Map of value and count
map<int,int> Cntmap;
public:
void push(int val)
{
// Find val in map
// if found then increment map count
// else insert a pair (val,1)
}
int pop( )
{
// Find the Key in Cntmap with max value
// using std::max_element
// Decrement the Cntmap count for the popped val
}
}
谁能帮助我正确的方法?
有趣的问题,因为在push
中,你抬头使用键,并在pop
中使用映射值。 std::map
立即支持第一个:您所要做的就是:
++ CntMap[ val ];
如果键不是,[]
运算符将插入一个条目present,使用其默认值初始化映射类型构造函数,对于int
会导致0
。 你甚至没有需要if
.
二是比较难。 然而,评论给出了解决方案:您只需要一个自定义Compare
,这需要两个 std::pair<int, int>
,并比较第二个元素。 std::max_element
会将迭代器返回到您所在的条目感兴趣,所以你可以直接使用它。 到目前为止一切顺利(和非常简单(,但您必须考虑错误条件:什么如果Cntmap
为空,则发生。 您可能希望删除元素,如果计数下降到0
(同样,很简单,因为你有一个迭代器指定条目,包括键和值(。
最后,如果这是一个面试问题,我肯定会指出pop
操作是O(n)
的,并且它可能值得(尽管要复杂得多(到维护二级索引,以便我可以找到最大值元素更快。 (如果我在面试,那将是我的下一个问题。 然而,显然对于高级程序员来说。
仅使用单个(简单(数据结构的问题在于,其中一个操作必须是线性的(它必须搜索所有元素(,这还不够好。在您的情况下,我相信线性时间操作是pop
.
我的尝试:
-
有一个链表(将按频率排序(。
-
将值映射到链表中的节点。
-
若要推送,请在映射中查找值以获取链接列表节点。
-
如果找到,请增加频率并适当地移动节点以保持链表排序。
-
如果未找到,请将频率设置为 1,然后插入到链接表中的适当位置。
-
-
要弹出,请降低链表第一个节点的频率并适当地移动它以保持链表的排序,并返回适用的值。
如果有许多节点具有相同的频率,您可能会遇到一些非常糟糕的最坏情况行为。应该可以通过拥有某种链表的链接列表来获得恒定的时间添加/递增/减少,大型链表中的每个节点代表一个特定的频率,每个链表代表具有该频率的所有节点。
通过上述优化,pop 可以是 O(1(,推送可以是 O(log n(。如果使用unordered_map
(C++11(,则推送可以是 O(1(。
另一个(可能稍微简单一些(的选择是做一些类似于上面的事情,但使用heap
而不是链接列表。
的情况下,Max-Heap 会更好,而不是 Map。您可以以类似的方式维护计数器。请注意,堆的键将是计数,而不是实际值本身。当您必须插入一个值时,请搜索该值,如果找到,则将其键递增,否则,将带有键的值插入为 1。希望这有帮助。
解决方案可能是包装Boost.Bimap(组织使用boost吗?(。 有了这个,您可以创建一个容器,该容器在一个方向上提供有序访问,并在另一个方向上进行哈希处理。您的推送和弹出实现将使用 bimap 的替换函数。
- QT通过C++添加映射QML项目
- Visual Studio 中的 CMake 项目:如何添加其他包含和库目录?
- 尝试将 boost::stacktrace 添加到 CMake 项目时出现构建错误
- 从文本文件在组合框中添加项目
- 如何在视觉c ++项目中添加箭头键作为修饰键Microsoft
- 如何将 Lua 添加到C++项目
- 将项目添加到队列时运行线程
- Qt - 为什么Visual Studio 2019在qml资源中添加10Mb文件后无法再编译我的项目?
- 添加项目后C find()函数不起作用
- 如何在向列表中添加项目的同时迭代列表
- 如何在Qt中添加项目时保持在同一滚动位置
- 使用 push_back() 在向量中添加项目,向量的大小会增加但无法从向量中读取值
- 从键盘向列表中添加项目
- C++添加项目
- Qt QGraphicsScene缓慢添加项目
- 如何通过鼠标单击在QGraphicsView中选择位置并添加项目
- 智能感知和代码建议在添加c++项目后无法在Visual Studio 2013中工作
- 添加项目到CTreectrl c++
- Qt QTreeWidget逐个添加项目
- 在c++ Builder XE8中显示/添加项目到某些组合框