算法-栈思想

一、实现一个特殊功能的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

输入
[[1,3],[1,2],[1,1],[3],[2],[3]]
返回值
[1,2]
备注:有三种操作种类,op1表示push,op2表示pop,op3表示getMin。你需要返回和op3出现次数一样多的数组,表示每次getMin的答案。
思想:2个栈实现,一个进行基本功能操作,另一个记录最小元素

def getMinStack(self, op):
    stack, minstack = [], [] #开辟一个栈记录最小值,最小值放栈顶
    res = []
    for i in range(len(op)):
        if op[i][0] == 1: #1表示要做push操作,如[1,3] 对3push
            stack.append(op[i][1])
            if not minstack or op[i][1] < minstack[-1]:
                #入栈时的元素如果小于最小栈的栈顶元素,需入minstack
                minstack.append(op[i][1])
        if op[i][0] == 2:
            if minstack and stack[-1] == minstack[-1]:
                minstack.pop()
            stack.pop()
        if op[i][0] == 3:
            res.append(minstack[-1])
    return res

二、用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思想:栈A实现入栈,栈B负责出栈。栈B为空时,从栈A取入并实现反转。

class Solution:
    def __init__(self):
        self.stack1, self.stack2 = [], []
    def push(self, node):
        # write code here
        self.stack1.append(node) #栈1负责入栈
    def pop(self): #栈2负责出栈。
        # return xx
        if self.stack2:  
            return self.stack2.pop()
        if not self.stack1: #栈2出完时判断栈1是否空
            return None
        while self.stack1: 
        #栈1依次出栈,入栈2;反转顺序后相当于出队列顺序
            self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

三、 用队列实现栈

双队列实现
思想:
1、任何时候两个队列总有一个是空的。
2、添加元素总是向非空队列中 add 元素。
3、取出元素的时候总是将元素除队尾最后一个元素外,导入另一空队列中,最后一个元素出队。

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue1 = []
        self.queue2 = []
        return None

    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        if not self.queue1 and not self.queue2:
            self.queue1.append(x)
        elif self.queue1 and not self.queue2:
            self.queue2.append(x)
            while self.queue1:
                self.queue2.append(self.queue1.pop(0))
        elif not self.queue1 and self.queue2:
            self.queue1.append(x)
            while self.queue2:
                self.queue1.append(self.queue2.pop(0))

    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        if self.queue1 and not self.queue2:
            return self.queue1.pop(0)
        elif self.queue2 and not self.queue1:    
            return self.queue2.pop(0)
        return None

    def top(self) -> int:
        """
        Get the top element.
        """
        if self.queue1 and not self.queue2:
            return self.queue1[0]
        elif self.queue2 and not self.queue1:    
            return self.queue2[0]
        return None

四、根据四则运算计算结果

1、无括号情况,思想:利用栈,乘 除的优先级别先算。
如:12+13*10-4+6/2

	def Caluc(self, s):
		if not s:
			return
		sum, n = 0, len(s)
		stack = []
		num = 0
		for i in range(n):
			#记录每一项的值
			if s[i] >= '0' and s[i] <= '9':
				num = num *10 + int(s[i])
			else:  #此时遇到乘除后的符号项为止,才能确定好值。
				#前一项为乘除时,弹出计算后再放入
				if stack and stack[-1] == '*':
					stack.pop() #弹出运算符
					tmp = stack.pop() #弹出前一项数字
					stack.append(tmp*num) #压入计算后的值
					stack.append(s[i])    #此时新的运算符压入
					num = 0 #num重新计数
				elif stack and stack[-1] == '/':
					stack.pop() #弹出运算符
					tmp = stack.pop() #弹出前一项数字
					stack.append(tmp/num) #压入计算后的值
					stack.append(s[i])    #此时新的运算符压入
					num = 0 #num重新计数
				else:   # + 和 - 的情况
					stack.append(num) #直接压入数值和运算符
					stack.append(s[i])  
					num = 0
		#结束拿到值未压入栈
		if num != 0:
			if stack and stack[-1] == '*':
				stack.pop() #弹出运算符
				tmp = stack.pop() #弹出前一项数字
				stack.append(tmp*num) #压入计算后的值
			elif stack and stack[-1] == '/':
				stack.pop() #弹出运算符
				tmp = stack.pop() #弹出前一项数字
				stack.append(tmp/num) #压入计算后的值
			else:   # + 和 - 的情况
					stack.append(num) #直接压入数值和运算符
		#此时 12+13*10-4+6/2 变成 [12, '+', 130, '-', 4, '+', 3.0]
		sum += stack.pop(0)
		while stack:
			tmp = stack.pop(0)
			if tmp == '+':
				sum += stack.pop(0)
			elif tmp == '-':
				sum -= stack.pop(0)
		return sum	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值