225.用队列实现栈 -20200531
- 用临时队列接入原有队列,保证元素先进后出的顺序,再把临时队列复制到原来队列
- 队列是 queue.front(),栈是stack.top()
void push(int x) {
std::queue<int> temp_queue;
temp_queue.push(x);
while(!_data.empty()){
int temp=_data.front();
temp_queue.push(temp);
_data.pop();
}
while(!temp_queue.empty()){
_data.push(temp_queue.front());
temp_queue.pop();
}
}
232. 用栈实现队列 -20200531
同上,嘻嘻。
155. 最小栈 -20200601
新建一个最小值栈,记录每次的最小值状态,使getMin()函数的时间复杂度为O(1)
void push(int x) {
_data.push(x);
if(_min.empty()){
_min.push(x);
}else{
if(x<_min.top()){
_min.push(x);
}else{
_min.push(_min.top());
}
}
}
946. 验证栈序列 -20200601
-
用栈模拟栈的进出,若最后栈为空,则说明出栈队列正确。
-
栈顶元素与出栈队列相同时出栈
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> s;
int j = 0;//用来标记poped数组出栈的元素
for(int i = 0; i < pushed.size(); i ++) {
s.push(pushed[i]);//入栈pushed数组元素
//如果入栈元素为要出栈的元素,进行出栈,直到不需要出栈为止
while(!s.empty() && s.top() == popped[j]) {
s.pop();
j++;
}
}
return s.empty();
}
456. 132模式 -20200604
- 用一个数组储存每个值状态下的最小值,方便找‘1’
- 从后往前遍历,找到比栈顶部‘2’大的‘3’,再从最小值数组中看是否存在‘1’;
bool find132pattern(vector<int>& nums) {
if(nums.size()<3) return false;
stack<int> s;
vector<int> mins;
int Min=INT_MAX;
for(int i=0;i<nums.size();i++){//记录最小值
if(nums[i]<Min){
Min=nums[i];
}
mins.push_back(Min);
}
for(int i=nums.size()-1;i>0;i--){
//从后往前找第二个值
if(s.empty()||nums[i]<s.top()){
s.push(nums[i]);
}
while(s.top()<=mins[i]){
s.pop();
}
if(nums[i]>s.top()&&nums[i]>mins[i]&&s.top()>mins[i]){
return true;
}
}
return false;
}
20. 有效的括号 -20200607
- 入栈反括号更简洁!
- 注意测试例子“ ] ”
bool isValid(string s) {
if(s.length()==0) return true;
stack<char> data;
int length=s.length();
for(int i=0;i<length;i++){
if(s[i]=='}'||s[i]==')'||s[i]==']'){
if(!data.empty()&&s[i]==data.top()){
data.pop();
}else{
return false;//!测试例子:只有一个“]”
}
}
if(s[i]=='('){
data.push(')');
}else if(s[i]=='{'){
data.push('}');
}else if(s[i]=='['){
data.push(']');
}
}
if(data.empty()){
return true;
}else{
return false;
}
}
42. 接雨水 -20200609
- 没错,单调栈的典型例子!
- 其实还没有明白他的循环怎么进行的??
- 当出现高于栈顶的柱子时:1>说明可以对前面的柱子结算了2>计算已经到手的雨水,然后出栈前面更低的柱子
int trap(vector<int>& height) {
int ans=0;
stack<int> s;
for(int i=0;i<height.size();i++){
while(!s.empty()&&height[i]>height[s.top()]){
int cur=s.top();
s.pop();
if(s.empty()){
break;
}
int l=s.top();
int r=i;
int h=min(height[l],height[r])-height[cur];
ans+=(r-l-1)*h;
}
s.push(i);
}
return ans;
}
84. 柱状图中最大的矩形 -202006011
- 破案了破案了!因为单调栈内的元素是单调的!所以可以直接找到左边第一个比它大或者小的元素!
- 此题就是要找到左边界和右边界,即左边第一个比它小的和右边第一个比它小的,这样就是以该元素为高的最大矩形。
int largestRectangleArea(vector<int>& heights) {
if(heights.size()==0) return 0;
stack<int> s;
heights.push_back(0);//设置右边界
int maxArea=heights[0];
for(int i=0;i<heights.size();i++){
while(!s.empty()&&heights[i]<heights[s.top()]){
//找到右边第一个比它小的
int index=s.top();
int right=i;
s.pop();//左边第一个比它小的元素
int left=s.empty()?-1:s.top();//左边界
maxArea=max(maxArea,(right-left-1)*heights[index]);
}
s.push(i);
}
return maxArea;
}
215. 数组中的第K个最大元素 -202006013
- 创建大小为K的小顶堆,最后返回堆顶即是所求。
- C++ priority_queue 优先队列详解
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int,vector<int>,greater<int>> smallheap;
for(int i=0;i<nums.size();i++){
if(smallheap.size()<k){
smallheap.push(nums[i]);
}else if(nums[i]>smallheap.top()){
smallheap.pop();
smallheap.push(nums[i]);
}
}
return smallheap.top();
}