《面试算法 LeetCode 刷题班》——2. 栈、队列、堆

本文内容是基于小象学院——林沐 《面试算法 LeetCode 刷题班》,后期仍将对相关内容进行不定期更新!

2. 栈、队列、堆

文章目录

      • 2. 栈、队列、堆
        • LeetCode 225 使用队列(Q)实现栈(S) (E)
        • LeetCode 232 用栈实现队列(E)
        • LeetCode 155 Min Stack(E)
        • Poj 1363 合法的出栈序列(M)
        • LeetCode 215 第K个最大的元素(E)
        • LeetCode 295 寻找中位数(H)
        • LeetCode 224 简单的计算器 (H)

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 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 _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 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 _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 _s;
    	stack _min;
};

自己写的 RunTimeError???

Poj 1363 合法的出栈序列(M)

已知从1到n的数字序列,按顺序入栈,每个数字入栈后即可出栈,也可在栈中停留,等待后面的数字入栈出栈后,该数字出栈,求该数字序列的出栈序列是否合法?

思路: 使用栈与队列模拟入栈、出栈过程。

bool check_sequence(queue &order) {
	stack 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& nums, int k) {
		priority_queue,less> 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, greater> small_heap;
	priority_queue, less> big_heap;
};

LeetCode 224 简单的计算器 (H)

问题暂时等待详细学习后更新

你可能感兴趣的:(C++,数据结构,leetcode)