leetcode_02栈
栈
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
C++模板编程
S.top()∶取出栈顶
S.empty:判断栈是否为空
S.push()∶将x添加至栈
S.pop()∶弹出栈顶
S.size0:栈的存储元素个数
#include<iostream>
#include<queue>
using namespace std;
int main()
{
queue<int> Q;
if(Q.empty())
{
printf("Q is empty\n");
}
Q.push(5);//向队列中放入元素5;
Q.push(6);
Q.push(10);
printf("Q.front=%d\n",Q.front());
Q.pop();//出队,先入的先出 5出去
Q.pop();//先入先出,6出去
printf("Q.front= %d\n",Q.front());
Q.push(1);//向队列中放入1
printf("Q.back= %d\n",Q.back());//队尾数字
printf("Q.size=%d\n",Q.size());
return 0;
}
例1.用队列实现栈
使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-stack-using-queues
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析:队列是先进先出,栈是先进后出,用一个临时队列,考虑到队列先进先出,先将需要的数字押进临时栈中,此时新元素成为头部元素,再将所有元素从临时栈搞到栈中,此时新元素最先进入队列,从而保证最先出来,实现了后进先出。
#include<iostream>
#include<queue>
using namespace std;
class MyStack{
public: MyStack(){}
void push(int x)
{
queue<int> temp_queue;
temp_queue.push(x);
while(!_data.empty())
{
temp_queue.push(_data.front());
_data.pop();
}
while(!temp_queue.empty())
{
_data.push(temp_queue.front());
temp_queue.pop();
}
}
int pop()//栈顶元素弹出动作
{
int x=_data.front();//获取栈顶元素,即为队列头部元素
_data.pop();
return x;
}
int top()
{
return _data.front();
}
bool empty()
{
return _data.empty();
}
private:
queue<int> _data;
};
int main()
{
MyStack myStack;
myStack.push(1);
myStack.push(2);
myStack.push(3);
printf("栈顶元素为: %d\n",myStack.top());
printf("弹出元素为: %d\n",myStack.pop());
return 0;
}
例2.用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:用栈实现队列,必须使得新元素在栈底。用一个临时栈,先将所有元素导入临时栈,使得顺序倒置,然后将新元素导入临时栈,从临时栈中向栈倒数据,从而新元素在最底下。
#include<iostream>
#include<stack>
using namespace std;
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
std::stack<int>temp_stack;//将栈中元素临时push到栈中
while(!_data.empty())
{
temp_stack.push(_data.top());
_data.pop();
}
temp_stack.push(x);
while(!temp_stack.empty())
{
_data.push(temp_stack.top());
temp_stack.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int x=_data.top();
_data.pop();
return x;
}
/** Get the front element. */
int peek() {
return _data.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return _data.empty();
}
private:std::stack<int>_data;
};
例3.最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:同时设置一个栈存储最小值,比较新元素,如果更小则更新压入最小值栈,不小则压入重复值,删除时同时弹出。
#include<iostream>
#include<stack>
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x)
{
_data.push(x);
if(_min.empty())
_min.push(x);
else{
if(x>_min.top())
{x=_min.top();}
_min.push(x);}
}
void pop() {
_data.pop();
_min.pop();
}
int top() {
return _data.top();
}
int getMin() {
return _min.top();
}
private:
std::stack<int>_data;
std::stack<int>_min;
};
int main()
{
MinStack minStack;
minStack.push(-2);
printf("top=[%d]\n",minStack.top());
printf("top=[%d]\n",minStack.getMin());
minStack.push(0);
printf("top=[%d]\n",minStack.top());
printf("top=[%d]\n",minStack.getMin());
}
例4.合法的输出序列
给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。
示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-stack-sequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
bool check_is_valid_orders(queue<int>&order)
{
stack<int>s;//S为模拟栈
int n=order.size();
printf("n=%d\n",n);
for(int i=1;i<=n;i++)
{
s.push(i);
while(order.front()==s.top()&&!s.empty())
{
s.pop();
order.pop();
printf("order.front(): %d\n",order.front());
printf("s.top(): %d \n",order.front());
}
}
if(s.empty())
{return true;}
return false;
}
int main()
{
queue<int>order;
order.push(3);
order.push(2);
order.push(1);
order.push(4);
order.push(5);
if(check_is_valid_orders(order))
{printf("yes");}
else
printf("No");
return 0;
}
堆
二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;
最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
#include<iostream>
#include<queue>
using namespace std;
int main()
{
priority_queue<int, vector<int>, less<int>> big_heap;//最大堆的定义方法
priority_queue<int, vector<int>, greater<int>> samll_Heap;//最小堆定义方法
if(big_heap.empty())
printf("big_heap is empty\n");
int test[]={6,10,1,7,99,4,33};
for(int i=0;i<7;i++)
{
big_heap.push(test[i]);
}
printf("big_heap.top=%d\n",big_heap.top());
big_heap.push(1000);
printf("big_heap.top=%d\n",big_heap.top());
for(int i=0;i<3;i++)
{
big_heap.pop();
}
printf("big_heap.top=%d\n",big_heap.top());
printf("big_heap.size()=%d\n",big_heap.size());
return 0;
}
例1.数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
思路:比如要寻找第k大的数,则建立大小为k的一个堆,
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
class Solution {
public:
int findKthLargest(vector<int>& nums, int k)
{
priority_queue<int, vector<int>, greater<int>>Q;
for(int i=0;i<nums.size();i++)
{
if(Q.size()<k)
Q.push(nums[i]);
else if(Q.top()<nums[i])
{
Q.pop();
Q.push(nums[i]);
}
}
return Q.top();//返回栈顶
}
};
int main()
{
Solution s1;
vector<int>nums;
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
int k=3;
printf("%d\n",s1.findKthLargest(nums,k));
return 0;
}
{
Q.pop();
Q.push(nums[i]);
}
}
return Q.top();//返回栈顶
}
};
int main()
{
Solution s1;
vectornums;
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
int k=3;
printf("%d\n",s1.findKthLargest(nums,k));
return 0;
}