Leetcode学习之栈、队列、堆(2)

开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!


Leetcode学习之栈、队列、堆(2)



1、包含min函数的栈 Leetcode 155.

题目来源 L e e t c o d e   155.   M i n   S t a c k Leetcode \ 155. \ Min \ Stack Leetcode 155. Min Stack
题目描述:设计一个栈,支持 p u s h ( x ) 、 p o p ( ) 、 t o p ( ) 、 g e t M i n push(x)、pop()、top()、getMin push(x)pop()top()getMin操作,其中 g e t M i n ( ) getMin() getMin()返回栈内最小元素
要求描述
在这里插入图片描述
思路首先考虑一个变量能否记录上述所有状态的最小值
在这里插入图片描述因此,使用另一个栈,存储各个状态最小值
在这里插入图片描述
测试代码

#include <stdio.h>
#include <stack>
using namespace std;

class MinStack {
public:
	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:
	stack<int> _data;//数据栈
	stack<int> _min;//最小值栈
};



2、合法的出栈序列

题目来源 p o j   1363   R a i l s poj \ 1363 \ Rails poj 1363 Rails
题目描述已知从1至n的数字序列,按顺序入栈,每个数字入栈后即可出栈,也可在栈中停留,等待后面的数字 入栈 出栈 后,该数字再出栈,求数字序列的出栈序列是否合法
要求描述
在这里插入图片描述思路:使用栈与队列模拟入栈、出栈过程
在这里插入图片描述测试代码:

#include <stack>
#include <queue>
#include <iostream>

using namespace std;

bool check_is_valid_order(queue<int> &order) {  //检查序列(存储在队列中)
	stack<int> s;//s为模拟栈
	int  n = order.size();//n为序列长度,将1-n入栈
	for (int i = 1; i <= n; i++) {
		s.push(i);//将i入栈
		while (!s.empty()&&order.front()==s.top())
		{
			s.pop();//只要s不空且队列头部与栈顶相同,即弹出元素
			order.pop();
		}
	}
	if (!s.empty()) {
		return false;
	}
	return true;
}


3、简单的计算器 Leetcode 224.

题目来源: L e e t c o d e   224.   B a s i c   C a l c u l a t o r Leetcode \ 224. \ Basic \ Calculator Leetcode 224. Basic Calculator
题目描述:设计一个计算器,输入一个字符串存储的数学表达式,可以包括"("、“)”、“+”、“-”四种符合的数学表达式,输入的数学表达式字符串保证合法的,输入的数学表达式中可能存在空格字符。
要求描述

在这里插入图片描述
思路栈内元素计算,栈可以用来去括号,处理优先级问题遇见 ‘(’ 不能计算,直到遇到 ‘)’ 才继续计算
字符串处理(状态机的思想)
在这里插入图片描述
测试代码:

#include <string>
#include <stack>
using namespace std;

class Solution {
public:
	int Calculate(std::string s) {
		static const int state_begin = 0;//开始状态,状态用常量表示
		static const int number_state = 1;//数字状态
		static const int operation_state = 2;//操作符状态
		stack<int> number_stack;//数字栈
		stack<char> operation_stack;//操作符栈

		int number = 0;
		int state = state_begin;
		int compuate_flag = 0;//记录要不要计算,初始化

		for (int i = 0; i < s.length(); i++) {
			if (s[i] == ' ') {
				continue;
			}
			switch (state)//状态切换
			{
			case state_begin:
				if (s[i] >= '0'&&s[i] <= '9') {
					state = number_state; //数字状态
				}
				else{
					state = operation_state;//操作符状态
				}
				i--;
				break;

			case number_state:
				if (s[i] >= '0'&&s[i] <= '9') {
					number = number * 10 + s[i] - '0';
				}
				else
				{
					number_stack.push(number);  //数字栈
					if (compuate_flag == 1) { //开始计算
						compute(number_stack, operation_stack);
					}
					number = 0;
					i--;
					state = operation_state;
				}
				break;

			case operation_state:
				if (s[i] == '+' || s[i] == '-') {
					operation_stack.push(s[i]);
					compuate_flag = 1;
				}
				else if (s[i] == '(') {
					state = number_state;
					compuate_flag = 0;//左括号不能计算
				}
				else if (s[i] >= '0'&&s[i] <= '9') {
					state = number_state;
					i--;
				}
				else if (s[i] == ')') { //右括号计算
					compute(number_stack, operation_stack);
				}
				break;
			}
		}
		if (number != 0) {
			number_stack.push(number);
			compute(number_stack, operation_stack);
		}
		if (number == 0 && number_stack.empty()) {
			return 0;
		}
		return number_stack.top();
	}

	void compute(stack<int> &number_stack, stack<char> &operation_stack) {//传引用,防止数据过大,拷贝出问题
		if (number_stack.size() < 2) {
			return;
		}
		int num2 = number_stack.top();
		number_stack.pop();
		int num1 = number_stack.top();
		number_stack.pop();

		if (operation_stack.top() == '+') {
			number_stack.push(num1 + num2);
		}
		else if (operation_stack.top() == '-'){
			number_stack.push(num1 - num2);
		}
		operation_stack.pop();	
	}
};

int main() {
	string s = "1+121-(14+(5-6))";
	Solution solve;
	printf("%d\n", solve.Calculate(s));
	system("pause");
	return 0;
}

字符串转换成数字:

number = number * 10 + s[i]-'0'//number*10表示从高位开始,往下乘10
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值