一、有效的括号
【题号】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:出栈的时候ÿ