本文内容是基于小象学院——林沐 《面试算法 LeetCode 刷题班》,后期仍将对相关内容进行不定期更新!
2. 栈、队列、堆
文章目录
1.栈: 先进后出
- S.push(x) : 将x压入栈顶
- S.pop() : 弹出栈顶
- S.size() : 栈中元素个数
- S.empty() : 栈是否为空
- S.top() : 栈顶元素
2.队列:先进先出
- Q.push(x) : 将x压入队列
- Q.pop() : 弹出队列头部元素
- Q.size() : 队列中元素个数
- Q.empty() : 队列是否为空
- Q.front() : 队列头部元素
- Q.back() : 队列尾部元素
LeetCode 225 使用队列(Q)实现栈(S) (E)
设计一个栈,支持如下操作,
Implement the following operations of a stack using queues.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
empty() -- Return whether the stack is empty.
这些操作的算法复杂度需要在常数级,O(1), 栈的内部存储数据的结构为队列,队列的方法只能包括 push
题目:
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
queue<int> tmp_q;
tmp_q.push(x);
while (!_data.empty())
{
tmp_q.push(_data.front());
_data.pop();
}
while (!tmp_q.empty())
{
_data.push(tmp_q.front());
tmp_q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int tmp_pop=0;
tmp_pop = _data.front();
_data.pop();
return tmp_pop;
}
/** Get the top element. */
int top() {
return _data.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return _data.empty();
}
private:
queue<int> _data;
};
LeetCode 232 用栈实现队列(E)
Implement the following operations of a queue using stacks.
push(x) -- Push element x to the back of queue.
pop() -- Removes the element from in front of queue.
peek() -- Get the front element.
empty() -- Return whether the queue is empty.
Example:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // returns 1
queue.pop(); // returns 1
queue.empty(); // returns false
代码:
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stack<int> tmp_s;
while (!_s.empty())
{
tmp_s.push(_s.top());
_s.pop();
}
tmp_s.push(x);
while (!tmp_s.empty())
{
_s.push(tmp_s.top());
tmp_s.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int value = 0;
value = _s.top();
_s.pop();
return value;
}
/** Get the front element. */
int peek() {
return _s.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return _s.empty();
}
private:
stack<int> _s;
};
#####225 和 232 的区别是要注意,用队列实现栈和用栈实现队列,都是需要借助一个辅助队列(栈),但中间变量插入值的时机不一样。
LeetCode 155 Min Stack(E)
思路: 需要常数时间返回这个栈的最小值,就是保证每一次最小值都是在栈顶,直接pop就可以了,所以需要新建一个栈
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
提交代码:
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
_s.push(x);
if (_min.empty())
{
_min.push(x);
}
else
{
if (x>_min.top())
{
_min.push(_min.top());
}
else
{
_min.push(x);
}
}
}
void pop() {
_s.pop();
_min.pop();
}
int top() {
return _s.top();
}
int getMin() {
return _min.top();
}
private:
stack<int> _s;
stack<int> _min;
};
自己写的 RunTimeError???
Poj 1363 合法的出栈序列(M)
已知从1到n的数字序列,按顺序入栈,每个数字入栈后即可出栈,也可在栈中停留,等待后面的数字入栈出栈后,该数字出栈,求该数字序列的出栈序列是否合法?
思路: 使用栈与队列模拟入栈、出栈过程。
bool check_sequence(queue<int> &order) {
stack<int> S;
int n = order.size();
for (int i = 1; i <= n; i++) {
S.push(i);
while (!S.empty() && S.top() == order.front())
{
S.pop(); // 执行下面语句的条件是 S 不为空,所以判断条件里要加上,否则会报错
order.pop();
}
}
if (S.empty())
{
return true;
}
return false;
}
二叉堆,最小(大)值先出的完全二叉树
LeetCode 215 第K个最大的元素(E)
使用优先级队列,最大堆的话可以直接入队然后根据K指弹出对应个最大值, 最小值堆则要维护一个只包含K个数的最小堆
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>,less<int>> Q;
for (auto a : nums)
Q.push(a);
for (int i = 0; i < k - 1; i++)
Q.pop();
return Q.top();
}
};
LeetCode 295 寻找中位数(H)
构建两个最大最小堆。
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
if (big_heap.empty())
{
big_heap.push(num);
}
else {
if (small_heap.size() > big_heap.size())
{
if (num < small_heap.top())
{
big_heap.push(num);
}
else
{
big_heap.push(small_heap.top());
small_heap.pop();
small_heap.push(num);
}
}
else if (small_heap.size() < big_heap.size())
{
if (num < big_heap.top())
{
small_heap.push(big_heap.top());
big_heap.pop();
big_heap.push(num);
}
else
{
small_heap.push(num);
}
}
else if (small_heap.size() == big_heap.size())
{
if (num > small_heap.top())
{
small_heap.push(num);
}
else
{
big_heap.push(num);
}
}
}
}
double findMedian() {
if (small_heap.size() == big_heap.size())
{
return (double)(small_heap.top() + big_heap.top()) / 2;
}
if (small_heap.size() > big_heap.size())
{
return (double)small_heap.top();
}
else
{
return (double)big_heap.top();
}
}
private:
priority_queue<int, vector<int>, greater<int>> small_heap;
priority_queue<int, vector<int>, less<int>> big_heap;
};
LeetCode 224 简单的计算器 (H)
问题暂时等待详细学习后更新