#include <iostream>
#include <stack>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string>
using namespace std;
//最小栈
class MinStack
{
public:
stack<int>st;
stack<int>minSt;
void push(int x)
{
st.push(x);
if(minSt.empty() || x <= minSt.top())
{
minSt.push(x);
}
}
void pop()
{
int top = st.top();
if(top == minSt.top())
{
minSt.pop();
}
}
int top()
{
return st.top();
}
int getMin()
{
return minSt.top();
}
};
//两个栈实现队列
class Myqueue{
public:
stack<int>st;
stack<int>queue;
void push(int x)
{
st.push(x);
}
int top()
{
if(queue.empty())
{
while(!st.empty())
{
int val = st.top();
st.pop();
queue.push(val);
}
}
return queue.top();
}
int pop()
{
top();
int val = queue.top();
return val;
}
bool empty()
{
return queue.empty() && st.empty();
}
};
//两个队列实现一个栈
class MyStack{
public:
queue<int>q1,q2;
void push(int x)
{
if(q1.empty())q1.push(x);
while(!q2.empty())
{
int val = q2.front();
q2.pop();
q1.push(val);
}
while(!q1.empty())
{
int val = q1.front();
q1.pop();
q2.push(val);
}
}
int pop()
{
int val = q2.front();
q2.pop();
}
int front()
{
return q2.front();
}
bool empty()
{
return q1.empty() && q2.empty();
}
};
class CircleQueue{
public:
vector<int>q;
int front = 0, rear = -1, size = 0;
CircleQueue(int k)
{
q = vector<int>(k);
}
bool isFull()
{
return size == q.size();
}
bool isEmpty()
{
return size == 0;
}
int Front()
{
return isEmpty() ? -1 :q[front];
}
int Rear()
{
return isEmpty() ? -1 : q[rear];
}
bool enqueue(int x)
{
if(!isFull())
{
rear = (rear + 1) % q.size();
q[rear] = x;
++size;
return true;
}
else
return false;
}
bool dequeu()
{
if(!isEmpty())
{
front = (front + 1) % q.size();
--size;
return true;
}
else
{
return false;
}
}
};
class MyDequeue{
public:
int front = 0, rear = -1, size = 0,capacity = 0;
vector<int>q;
MyDequeue(int k)
{
q = vector<int>(k);
capacity = k;
}
bool isFull()
{
return size == capacity;
}
bool isEmpty()
{
return size == 0;
}
int getFront()
{
return isEmpty() ? -1:q[front];
}
int getRear()
{
return isEmpty() ? -1:q[rear];
}
bool insertFirst(int x)
{
if(isFull())return false;
if(--front < 0) front += capacity;
q[front] = x;
++size;
if(size == 1)rear = front;
return true;
}
bool insertLast(int x)
{
if(isFull())return false;
rear = (rear + 1) % capacity;
q[rear] = x;
++size;
return true;
}
bool deleteFirst()
{
if(isEmpty())return false;
front = (front + 1) % capacity;
--size;
return true;
}
bool deleteLast()
{
if(isEmpty())return false;
if(--rear < 0)rear += capacity;
--size;
return true;
}
};
void print(const vector<int>& res)
{
for(int num : res)
{
cout << num << " ";
}
cout << endl;
}
//递增栈
vector<int>nextGreater(const vector<int>& nums)
{
int n = nums.size();
vector<int>res(n);
stack<int>st;
for(int i = n - 1; i >= 0; --i)
{
while(!st.empty() && nums[i] >= st.top())
{
st.pop();
}
res[i] = st.empty() ? -1:st.top();
st.push(nums[i]);
}
return res;
}
vector<int> nextGreaterElement(const vector<int>& nums1, const vector<int>& nums2)
{
unordered_map<int,int>map;
stack<int>st;
int n = nums2.size();
for(int i = n - 1; i >= 0; --i)
{
while(!st.empty() && nums2[i] >= st.top())
{
st.pop();
}
map[nums2[i]] = st.empty() ? -1:st.top();
st.push(nums2[i]);
}
n = nums1.size();
vector<int>res;
for(int i = 0 ; i < n; ++i)
{
if(map.find(nums1[i]) != map.end())
{
res.emplace_back(map[nums1[i]]);
}
else
{
res.emplace_back(-1);
}
}
return res;
}
vector<int>nextGreaterElement(const vector<int>& input)
{
int n = input.size();
vector<int>res(n);
stack<int>st;
for(int i = 2 * n - 1; i >= 0; --i)
{
while(!st.empty() && input[i % n] >= st.top())
{
st.pop();
}
res[i % n] = st.empty() ? -1 : st.top();
st.push(input[i % n]);
}
return res;
}
vector<int>dailyTemperatures(const vector<int>& tmp)
{
int n = tmp.size();
vector<int>res(n);
stack<int>st;
for(int i = n - 1; i >= 0; --i)
{
while(!st.empty() && tmp[i] >= tmp[st.top()])st.pop();
res[i] = st.empty() ? 0 : st.top() - i;
st.push(i);
}
return res;
}
string removeDuplicateLetters(string s) {
vector<int> vis(26), num(26);
for(char c:s)
{
++num[c-'a'];
}
string res;
for(char c:s)
{
if(!vis[c - 'a'])
{
while(!res.empty() && res.back() > c)
{
if(num[res.back() - 'a'] > 0)
{
vis[res.back() -'a'] = 0;
res.pop_back();
}
else
{
break;
}
}
vis[c - 'a'] = 1;
res.push_back(c);
}
--num[c - 'a'];
}
return res;
}
string removeKdigits(string s,int k)
{
stack<char>st;
for(char c:s)
{
while(!st.empty() && c < st.top() && k > 0)
{
st.pop();
--k;
}
st.push(c);
}
while(k-- > 0)st.pop();
bool zero = false;
string res = "";
while(!st.empty())
{
char c = st.top();
st.pop();
res.push_back(c);
}
reverse(res.begin(),res.end());
res = to_string(stoi(res));
return res;
}
int trap(const vector<int>& height)
{
int res = 0;
int n = height.size();
vector<int>left(n),right(n);
left[0] = height[0];
right[n-1] = height[n-1];
for(int i = 1; i < n; ++i)
{
left[i] = max(height[i],left[i-1]);
}
for(int i = n - 2; i >= 0; --i)
{
right[i] = max(height[i],right[i+1]);
}
for(int i = 0; i < n; ++i)
{
res += min(left[i],right[i]) - height[i];
}
return res;
}
int trapI(const vector<int>& nums)
{
stack<int>st;
int res = 0, n = nums.size();
for(int i = 0; i < n ;++i)
{
while(!st.empty() && nums[i] > nums[st.top()])
{
int pre = st.top();
st.pop();
if(st.empty())break;
int minHeight = min(nums[i],nums[st.top()]);
res += (minHeight - nums[pre]) * ( i - st.top() - 1);
}
st.push(i);
}
return res;
}
int largestRectangleArea(const vector<int>& nums)
{
stack<int>st;
int n = nums.size();
int res = 0;
for(int i = 0; i < n; ++i)
{
while(!st.empty() && nums[i] <= nums[st.top()])
{
int pre = st.top();
st.pop();
int preHeight = nums[pre];
int width = i - (st.empty() ? 0 :st.top() + 1);
res = max(res, preHeight * width);
}
st.push(i);
}
while(!st.empty())
{
int preHieght = nums[st.top()];
st.pop();
int width = n - (st.empty() ? 0 : st.top() + 1);
res = max(res,preHieght * width);
}
return res;
}
int main()
{
vector<int>nums{2,1,2,4,3};
print(nextGreater(nums));
//LeetCode496
vector<int>nums1 = {4,1,2};
vector<int>nums2 = {1,3,4,2};
print(nextGreaterElement(nums1,nums2));
//LeetCode503
vector<int>input{1,2,1};
print(nextGreaterElement(input));
//LeetCode739
vector<int>tmp{73,74,75,71,69,72,76,73};
print(dailyTemperatures(tmp));
//LeetCode316
string s = "bcabc";
cout << removeDuplicateLetters(s) << endl;
//LeetCode402
s = "10200";
int k = 1;
// s = "1433219";
// k = 3;
cout << removeKdigits(s,k) << endl;
//LeetCode42
vector<int>height{4,2,0,3,2,5};
cout << trap(height) << endl;
cout << trapI(height) << endl;
//LeetCode84
height = {2,1,5,6,2,3};
cout << largestRectangleArea(height) << endl;
return 0;
}