《剑指offer》--栈队列堆

《剑指offer》–栈队列堆

  1. 用两个栈实现队列
  2. 包含 min 函数的栈
  3. 栈的压入、弹出序列
  4. 最小的 K 个数
  5. 数据流中的中位数
  6. 字符流中第一个不重复的字符
  7. 滑动窗口的最大值
#include<vector>
#include<stack>
#include<sstream>
#include<string>
#include<algorithm>
#include <queue>
//栈队列堆
using namespace std;


/*用两个栈来实现一个队列,完成队列的 Push ,Pop,Top,empty操作。*/
/*******************************************************************************/
class MyQueue {
private:
    stack<int> stack1, stack2;
public:
    MyQueue() {

    }


	int push(int x)
	{
		stack1.push(x);
	}

	//弹出对应的数据
	int pop() {
		if (stack1.empty()) {
			while (stack2.empty()) {
				stack2.push(stack1.top());
				stack1.pop();

			}

		}
		int front = stack2.top();
		stack2.pop();
		return front;
	}

	int top() {
		if (stack1.empty()) {
			while (stack2.empty()) {
				stack2.push(stack1.top());
				stack1.pop();

			}

		}
		return stack2.top();
	}


	//判断是否是空 
	int empty()
	{
		return stack1.empty() && stack2.empty();
	}
};


/*******************************************************************************/

/*包含 min 函数的栈*/
/*******************************************************************************/
class MinStack {
private:
	stack<int> dataStack, minStack;
public:
	MinStack() {

	}
	void push(int node) {
		dataStack.push(node);
		int temp = minStack.top();
		minStack.push(minStack.empty() ? node :min(temp, node));

	}

	void pop() {
		 dataStack.pop();
		 minStack.pop();
	}

	int top() {
		return dataStack.top();
	}

	int minstack() {
		return minStack.top();
	}



};
/*******************************************************************************/

/*栈的压入、弹出序列*/
/*输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。

例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,
但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。*/
/*******************************************************************************/
bool IsPopOrder(vector<int> pushSequence, vector<int> popSequence)
{
	stack<int>pushs;
	int n = pushSequence.size();
	for (int pushIndex = 0, popIndex = 0; pushIndex < n;pushIndex++ ) {
		pushs.push(pushSequence[pushIndex]);
		while (popIndex<n && !pushs.empty() && pushs.top() == popSequence[popIndex])
		{

			pushs.pop();
			popIndex++;

		}
	}

	cout << pushs.empty() << endl;
	return pushs.empty();

}

/*******************************************************************************/
/*最小K个数,利用*/   
/*******************************************************************************/
vector<int> GetLeastNumbers_Solution(vector<int>&nums, int k) {

	priority_queue<int> pq;
	for (int i = 0; i < k; i++) {
		pq.push(nums[i]);
	}
	for (int i = k; i < nums.size(); i++) {
		if (nums[i] < pq.top()) {
			pq.pop();
			pq.push(nums[i]);
		}
	}
	vector<int> res;
	while (!pq.empty()) {
		res.push_back(pq.top());
		pq.pop();
	}
	reverse(res.begin(), res.end());
	return res;


}


//滑动窗口的最大值


/*数据流中的中位数*/
class MedianFinder {
public:
	/** initialize your data structure here. */
	MedianFinder() {

	}

	void addNum(int num) {
		if (maxHeap.empty() || num <= maxHeap.top()) {
			maxHeap.push(num);
		}
		else {
			minHeap.push(num);
		}
		// Rebalance the two heaps
		if (maxHeap.size() > minHeap.size() + 1) {
			minHeap.push(maxHeap.top());
			maxHeap.pop();
		}
		else if (minHeap.size() > maxHeap.size() + 1) {
			maxHeap.push(minHeap.top());
			minHeap.pop();
		}
	}

	double findMedian() {
		if (maxHeap.size() == minHeap.size()) {
			return (maxHeap.top() + minHeap.top()) / 2.0;
		}
		else if (maxHeap.size() > minHeap.size()) {
			return maxHeap.top();
		}
		else {
			return minHeap.top();
		}
	}

private:
	std::priority_queue<int, std::vector<int>, std::less<int>> maxHeap; // 大根堆
	std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap; // 小根堆
};


/*请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中
只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g"。
当从该字符流中读出前六个字符“google" 时,第一个只出现一次的字符是 "l"。*/

class FirstAppearingOnce{
private:
	int cnts[128] = { 0 };
	queue<int> meQueue;

public:
	void Insert(char ch) {
		cnts[ch]++;
		meQueue.push(ch);
		while (!meQueue.empty() && cnts[meQueue.front()] > 1)
			meQueue.pop();
	}

	char FirstAppearinOne() {
		return meQueue.empty() ? '#' : meQueue.front();
	}

};


//滑动窗口的最大值
int  maxInwondows(vector<int> nums, int k, vector<int> &result)
{

	vector<int> res;
	deque<int> q;
	for (int i = 0; i < nums.size(); i++) {
		// 如果队列不为空且当前队列尾部元素小于等于当前元素,则将队列尾部元素出队
		while (!q.empty() && nums[q.back()] <= nums[i]) {
			q.pop_back();
		}
		// 将当前元素入队
		q.push_back(i);
		// 如果队列头部元素已经不在当前窗口中,将其出队
		if (q.front() <= i - k) {
			q.pop_front();
		}
		// 当窗口大小达到k时,将队列头部元素加入结果数组
		if (i >= k - 1) {
			res.push_back(nums[q.front()]);
		}
	}

	return 0;
}











/*******************************************************************************/
void test_GetLeastNumbers_Solution()
{
	vector<int> nums = { 3, 2, 1, 5, 4, 2, 6, 7, 2 };
	int k = 4;
	vector<int> res = GetLeastNumbers_Solution(nums, k);
	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << " ";
	}
	cout << endl;
}




int main()
{
	test_GetLeastNumbers_Solution();


	getchar();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值