【Leetcode刷题笔记】栈

一、有效的括号

【题号】20
【题目描述】
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:
输入: “()”
输出: true
示例 2:
输入: “()[]{}”
输出: true
示例 3:
输入: “(]”
输出: false
示例 4:
输入: “([)]”
输出: false
示例 5:
输入: “{[]}”
输出: true
【常规解法】
1.初始化栈 S。
2.一次处理表达式的每个括号。
3.如果遇到开括号,我们只需将其推到栈上即可。这意味着我们将稍后处理它,让我们简单地转到前面的 子表达式。
4.如果我们遇到一个闭括号,那么我们检查栈顶的元素。如果栈顶的元素是一个 相同类型的 左括号,那么我们将它从栈中弹出并继续处理。否则,这意味着表达式无效。
5.如果到最后我们剩下的栈中仍然有元素,那么这意味着表达式无效。
【我的代码】

class Stack(object):
    def __init__(self, limit=10):
        self.stack = [] #存放元素
        self.limit = limit #栈容量极限
    def push(self, data): #判断栈是否溢出
        if len(self.stack) >= self.limit:
            print('StackOverflowError')
            pass
        self.stack.append(data)
    def pop(self):
        if self.stack:
            return self.stack.pop()
        else:
            #raise IndexError('pop from an empty stack') #空栈不能被弹出
            return False
    def peek(self): #查看堆栈的最上面的元素
        if self.stack:
            return self.stack[-1]
    def is_empty(self): #判断栈是否为空
        return not bool(self.stack)
    def size(self): #返回栈的大小
        return len(self.stack)


class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack = Stack(len(s))
        for c in s:
            if (c == '(') or (c=='{') or (c=='['):
                stack.push(c)
            elif c==')':
                if(stack.pop()!='('):
                    return False
            elif c=='}':
                if(stack.pop()!='{'):
                    return False
            elif c==']':
                if(stack.pop()!='['):
                    return False
            else:
                return False
        if stack.is_empty():
            return True
        else:
            return False

【执行情况】
执行用时36ms rank 23.13%
消耗内存11.7MB rank 99.23%
【范例代码】

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """

        # The stack to keep track of opening brackets.
        stack = []

        # Hash map for keeping track of mappings. This keeps the code very clean.
        # Also makes adding more types of parenthesis easier
        mapping = {
   ")": "(", "}": "{", "]": "["}

        # For every bracket in the expression.
        for char in s:

            # If the character is an closing bracket
            if char in mapping:

                # Pop the topmost element from the stack, if it is non empty
                # Otherwise assign a dummy value of '#' to the top_element variable
                top_element = stack.pop() if stack else '#'

                # The mapping for the opening bracket in our hash and the top
                # element of the stack don't match, return False
                if mapping[char] != top_element:
                    return False
            else:
                # We have an opening bracket, simply push it onto the stack.
                stack.append(char)

        # In the end, if the stack is empty, then we have a valid expression.
        # The stack won't be empty for cases like ((()
        return not stack

【分析】
1.我做这道题的时候专门定义了一个栈类,其实直接定义一个stack数组即可。直接使用stack.pop()以及stack.append()进行出栈和入栈操作,使用stack和not stack进行栈是否为空的判断。
2.我穷举了所有左右闭合的情况进行判断,判断语句很笨重。由于每一个右括号,都对应了一个专属的左括号,所以更好的方法是使用哈希表使用if char in mapping判断哈希表中是否有索引char,此处对应的是判断char是否为某右括号,如果有,则mapping[char]即为对应的左括号。
【拓展】
1.时间复杂度
定义了三个数组。数组1为常规的栈,数组2为左括号数组,数组3为括号对数组
通过与数组2比对,判断新输入字符是否是左括号,直接进栈。若不是左括号且栈不为空,则将栈顶字符与新输入的字符拼接,通过与数组3比对,判断是否能组成正确的括号对,若是,则将栈顶出栈。以上都不满足时即为输入错误。字符串穷尽后,通过判断栈中是否还有元素决定输出结果。
这里的栈不为空保证了后半句的数组不越界。即避免栈空时,错误输入一个右括号的情况
范例:时间消耗4ms

class Solution(object):
    def isValid(self, s):     
        stack, s1, s2 = [], ['(','[','{'], ['()','[]','{}']
        for n in s:
            if n in s1: stack.append(n)
            elif stack and stack[-1]+n in s2: stack.pop()
            else: return False
        return stack == []

二、最小栈

【题号】115
【题目描述】
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) – 将元素 x 推入栈中。
pop() – 删除栈顶的元素。
top() – 获取栈顶元素。
getMin() – 检索栈中的最小元素。

示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
【常规解法】
构建辅助栈,“以空间换时间”
辅助栈栈顶为当前最小值。
(一)同步辅助栈
辅助栈元素个数和数据栈元素个数相同。
辅助栈中的元素完全对应了数据栈中每一个元素入栈时的最小值。并将判断放在入栈阶段。
每当数据栈中入栈新元素时,判断新入栈的元素是否比目前最小值要小,若小则替换当前最小值,并在辅助栈中同步入栈最小值。
每当数据栈中出栈元素时,辅助栈同步出栈。
(二)非同步辅助栈
辅助栈元素个数和数据栈元素个数不相同。
入栈时,为最小值才同步入栈;出栈时,为最小值才同步出栈。
每当数据栈中入栈新元素时,若新元素小于或等于当前最小值,则替换最小值,并将该元素入辅助栈。
每当数据栈中出栈元素时,若出栈元素等于当前最小值时,辅助栈同步出栈。
(此处的或等于容易漏)
【我的代码】

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack=[]


    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.stack.append(x)


    def pop(self):
        """
        :rtype: None
        """
        if self.stack:
            return self.stack.pop()
        else:
            return False


    def top(self):
        """
        :rtype: int
        """
        if self.stack:
            return self.stack[-1]
        else:
            return False


    def getMin(self):
        """
        :rtype: int
        """
        if self.stack:
            minEle=self.stack[0]
        else:
            return False
        for temp in self.stack:
            if temp<minEle:
                minEle=temp
        return minEle

【执行情况】
在这里插入图片描述
【范例代码】

class MinStack:

    # 辅助栈和数据栈同步
    # 思路简单不容易出错

    def __init__(self):
        # 数据栈
        self.data = []
        # 辅助栈
        self.helper = []

    def push(self, x):
        self.data.append(x)
        if len(self.helper) == 0 or x <= self.helper[-1]:
            self.helper.append(x)
        else:
            self.helper.append(self.helper[-1])

    def pop(self):
        if self.data:
            self.helper.pop()
            return self.data.pop()

    def top(self):
        if self.data:
            return self.data[-1]

    def getMin(self):
        if self.helper:
            return self.helper[-1]

作者:liweiwei1419
链接:https://leetcode-cn.com/problems/min-stack/solution/shi-yong-fu-zhu-zhan-tong-bu-he-bu-tong-bu-python-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class MinStack:

    # 辅助栈和数据栈不同步
    # 关键 1:辅助栈的元素空的时候,必须放入新进来的数
    # 关键 2:新来的数小于或者等于辅助栈栈顶元素的时候,才放入(特别注意这里等于要考虑进去)
    # 关键 3:出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈,即"出栈保持同步"就可以了<
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值