我一开始没想太多,觉得把标准库里现有的数据结构拼一下,完全就可以了,这是我的代码:
class MinStack { private: multiset<int> sortedElems; list<int> stack; public: void push(int x) { sortedElems.insert(x); stack.push_back(x); } void pop() { if (stack.empty()){ return; } sortedElems.erase(sortedElems.find(stack.back())); stack.pop_back(); } int top() { return stack.back(); } int getMin() { return *sortedElems.cbegin(); } };
这个思路有点偷懒,就是你既然要求返回最小元素所用的时间是固定的,那么原先理论上需要用来查找的开销我就挪到别的地方去,没错,我把它们分摊到了 pop() he push() 上。
但毕竟我的这个算法很愚蠢,所以就算是返回最小值的时间变短了,但总时间还是很长,效率低下, 共用了 54ms。
当我的方法不算是最快的那一种的时候,我就会看一下讨论区里其他朋友的方法,结果果然发现了更高效的方法,原代码是 Java 版本,我改写了自己的一份 C++ 版本:
class MinStack { private: long long min = 0; stack<long long> _stack; public: void push(int x) { auto&& n = static_cast<long long>(x); if (_stack.empty()) { _stack.push(0L); min = n; return; } _stack.push(n - min); if (n < min){ min = n; } } void pop() { if (_stack.empty()){ return; } auto popedNum = _stack.top(); if (popedNum < 0L){ min -= popedNum; } _stack.pop(); } int top() { auto topNum = _stack.top(); if (topNum > 0) { return static_cast<int>(min + topNum); } return static_cast<int>(min); } int getMin() { return static_cast<int>(min); } };
这个算法很有意思,是一种空间换时间的策略,我之前的想法中,最小值和栈中存储的值是割裂开的,存储是存储,然后再单独求出最小值。
而这种方法就不同了,它是把最小值与每个值在 push() 时通过运算建立联系,并在 pop() 时通过逆运算求得原先的值,因此所用时间只有 28ms。
时间: 2024-10-24 13:24:56