刷题:栈的相关操作

1. 设计一个具有getMin功能的栈

要求:pop、push、getMin等函数的功能的时间复杂度都是O(1)。

思路:用两个标准栈来实现。其中一个栈用于存储数据(称为数据栈,stackData),另一个栈用于存储当前数据栈中的最小值(称为最小栈,stackMin)。

入栈规则:
假设入栈的数据为 num,则将其压入stackData中,然后判断stackMin是否为空。

  1. 如果stackMin 为空,则将num 也压入stackMin中。
  2. 如果stackMin 不为空,则比较 num 与 stackMin 栈顶元素的大小。
  3. 如果num 小于等于 stackMin 栈顶元素,则将num 压入stackMin中。
  4. 如果num 大于 stackMin 栈顶元素,则stackMin不做操作。

出栈规则:
将stackData的栈顶元素出栈,如该元素等于stackMin的栈顶元素,则stackMin将栈顶元素出栈。如该元素大于stackMin的栈顶元素,则stackMin不做操作。

获取栈中最小元素时,只需要输出stackMin的栈顶元素。

具体代码为:

class New_stack
{
public:
	New_stack();
	~New_stack();
	void push(int n);
	void pop();
	int top();
	int getMin();

private:
	stack<int> stack_data;
	stack<int> stack_min;
};

New_stack::New_stack()
{
}

New_stack::~New_stack()
{
}

void New_stack::push(int n)
{
	stack_data.push(n);

	if (stack_min.empty())
		stack_min.push(n);
	else if (n <= stack_min.top())
		stack_min.push(n);

}
int New_stack::top()
{
	return stack_data.top();
}
void New_stack::pop()
{
	if (stack_data.empty())
		cout << "The stack is empty !" << endl;
	if (stack_data.top() == stack_min.top())
		stack_min.pop();

	stack_data.pop();
}
int New_stack::getMin()
{
	if (stack_data.empty())
		cout << "The stack is empty !" << endl;
	return stack_min.top();
}

测试代码:

int main()
{
	
	cout <<"the stack who has getMin functon " << endl;
	New_stack stack_min;
	stack_min.push(10);
	stack_min.push(12);
	stack_min.push(5);
	stack_min.push(3);
	stack_min.push(54);

	for (int i = 0; i < 5; ++i)
	{
		cout << "the stack min value: " << stack_min.getMin() << endl;
		stack_min.pop();
	}
	return 0;
}

测试结果:
在这里插入图片描述

2. 用一个栈实现另一栈的排序

要求:一个栈中的元素为整型,现在将栈从顶到底按从大到小的顺序排序。只允许申请一个栈。除此之外,可以申请新的变量,但是不允许使用其他的数据结构。

思路:申请一个栈用于存储临时的排序结果(记为temp_stack),申请一个变量用于记录排序栈的栈顶元素(记为cur)。如果temp_stack为空,则将cur压人temp_stack中;如果temp_stack不为空且cur 小于等于temp_stack的栈顶元素,则将压入temp_stack中;如果temp_stack不为空且cur 大于temp_stack的栈顶元素,则需要将temp_stack栈中的元素压入排序栈中,直到cur值小于等于temp_stack的元素或temp_stack为空。用这种方式排序后,temp_stack栈从顶到底的元素顺序为从小到大的顺序。因此,还需要将temp_stack栈中的元素压入原始栈中。从而实现栈从顶到底按从大到小的顺序排序。

代码:

void sortStackbyStack(stack<int> &s)
{
	stack<int> temp_stack;
	int cur = 0;
	while (!s.empty())
	{
		cur = s.top();
		s.pop();
		while (!temp_stack.empty() && temp_stack.top() < cur)
		{
			s.push(temp_stack.top());
			temp_stack.pop();
		}
		temp_stack.push(cur);
	}
	while (!temp_stack.empty())
	{
		s.push(temp_stack.top());
		temp_stack.pop();
	}
}

测试代码:

int main()
{
    stack<int> s;
	cout << endl <<"用栈将另一个栈排序: " << endl;
	cout <<"    原始栈: " ;
	s.push(1); s.push(5); s.push(6); s.push(4); s.push(7);
	for (int i = 0; i < 5; ++i)
	{
		cout << s.top() << " ";
		s.pop();
	}
	cout << endl;
	cout << "    排序栈: ";
	s.push(1); s.push(5); s.push(6); s.push(4); s.push(7);
	sortStackbyStack(s);
	for (int i = 0; i < 5; ++i)
	{
		cout << s.top() << " ";
		s.pop();
	}
	cout << endl;
	return 0;
}

测试结果:
在这里插入图片描述

3.Next Greater Node In Linked List

Leetcode1019题

该题是查找链表中当前元素后面第一个大于当前元素值的元素。用暴力法解决该问题时间复杂度是O(n^2)。但是这种做法肯定难以让人满意。所以需要寻找一种更好的方法。

该问题的最优解是用栈来处理。具体思路为:
栈内存放的是 结点的编号。 每压入一个编号前,先检查该编号对应元素是否大于栈顶的编号对应元素,、如果大于,则栈顶编号出列,且栈顶编号对应元素的greater为 当前编号对应元素。如果不大于,则继续压栈。

这样做的目的是 用栈来记录哪些节点未找到它的目标节点。没找到目标节点的节点就保留在栈中,那些找到目标节点的节点则记录它的目标节点然后出栈。

具体代码为:

vector<int> nextLargerNodes(ListNode* head) {
	stack<int> hole;
	vector<int> values;
	for (auto node = head; node; node = node->next)//获取链表中节点的值,将其保存在values中,以便进行处理。
	 {
		values.push_back(node->val);
	}
	vector<int> res(values.size(), 0);
	for (auto i = 0; i < values.size(); ++i) 
	{
		//查找目标值的过程
		while (!hole.empty() && values[i] > values[hole.top()]) 
		{
			res[hole.top()] = values[i];
			hole.pop();
		}
		hole.push(i);
	}
	return res;
}

运行结果为:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值