Задание было предложено на тесте в комании Яндекс.
Нужно реализовать стек с операцией max()
, которая должна возвращать максимальный элемент в стеке.
Входные данные:
5
push 2
push 5
max
pop
max
Результат:
5
2
Входные данные:
1
max
Результат:
-2147483648
Входные данные:
2
push 2
max
Результат:
2
#include <iostream>
#include <stack>
#include <map>
#include <vector>
using namespace std;
class StackMax {
private:
stack<int> Stack;
map<int, int> Map;
map <int, int>::iterator Max;
void setMax();
public:
StackMax();
void pop();
void push(int i);
int max();
};
StackMax::StackMax()
{
Max = Map.end();
}
int StackMax::max()
{
int r = INT_MIN;
if(Max != Map.end()) {
r = Max->first;
}
return r;
}
void StackMax::setMax()
{
Max = Map.end();
if(Map.size() > 0) {
Max--;
}
}
void StackMax::pop()
{
map <int, int>::iterator found;
int current, count;
bool new_max = false;
if(Stack.empty() == true) {
// стек пустой, ничего не делаем
return;
}
current = Stack.top();
if((found = Map.find(current)) != Map.end()) {
count = found->second - 1;
if(count > 0) {
// уменьшаем счетчик
Map[current] -= 1;
} else {
// пора удалить элемент
new_max = current == max();
Map.erase(current);
}
}
if(new_max == true) {
setMax();
}
Stack.pop();
}
// При добавлении в стек нового элемента, обновляется карта Map,
// то есть, если в коллекции есть уже подобный элемент, увеличивается счетчик
// для этого элемента
// если элемент новый, он добавляется в Map со значением счетчика равным 1.
// При поступлении в коллекцию элемента, превышающего максимальный,
// Изменяется итератор, указывающий на максимальный элемент
void StackMax::push(int i)
{
map <int, int>::iterator found;
int current_max = max();
bool new_max = current_max == INT_MIN || i > max();
if(Stack.empty() == true) {
// стек пока пустой
Map[i] = 1;
} else if((found = Map.find(i)) == Map.end()) {
// такого элемента нет в стеке
Map[i] = 1;
} else {
// такой элемент есть в стеке
found->second += 1;
}
if(new_max == true) {
setMax();
}
Stack.push(i);
}
int main()
{
StackMax s;
int n;
string op, x;
vector<string> out;
// ввод данных
cin >> n;
for (int i = 0; i < n; i++) {
cin >> op; // operand
if(op == "push") {
cin >> x;
s.push( stoi(x) );
} else if (op == "pop") {
s.pop();
} else if (op == "max"){
out.push_back( to_string(s.max()) );
}
}
// вывод результатов
for(auto x : out) {
cout << x << endl;
}
return 0;
}