class Solution:
def isValid(self, s: str) -> bool:
#利用栈的先入后出原理,当字符串中的字符和字典中的key值相同入栈,如果栈顶的元素在字典中对应的value和字符串当前指针不符,就退出。因为栈的pop操作,栈空报错,因此提前给栈输入一个值。
dict_kuohao = {'(': ')', '{': '}', '[': ']','?':'?'}
stack = ['?']
for i in s:
if i in dict_kuohao:
stack.append(i)
elif dict_kuohao[stack.pop()] != i:
return False
return len(stack) == 1#如果最后的栈只剩?,则括号匹配,否则就一定不匹配
class Solution:
def minAddToMakeValid(self, s: str) -> int:
need = 0 #记录右括号的插入量
res = 0 #记录左括号的插入量
for i in s: #遍历字符串
if i == '(': #如果是左括号
need += 1 #右括号需求+1
if i == ')': #碰到右括号时
need -= 1 #给右括号需求-1
if need == -1: #如果右括号需求是-1
need = 0 # 让右括号需求归零
res += 1 #此时需要插入左括号
return need + res #返回左右括号的插入和
class Solution:
def minInsertions(self, s: str) -> int:
need = 0 #右括号的需求数
res = 0 #括号的插入数,因为左括号必须在两个右括号之前,所以当需求数是奇数时,要在左括号前插入一个右括号,并把需求数减一
for i in s:
if i == '(':
need += 2 #遇到左括号,右括号的需求+2
if need % 2 == 1: #如果右括号的需求是奇数
need -= 1 #给需求数减一
res += 1 #插入一个右括号
if i == ')':
need -= 1
if need == -1:
res += 1 #插入一个左括号
need = 1
return need + res
栈是一种先进后出的数据结构,下面解决单调栈解决的一类问题:下一个更大元素
python中对栈和队列的内置函数如下:
一、单调栈模板
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
num = nums + nums #把数组拼接到一块,这样不会出现超下标
stack = [] #栈,存储当前倒着进来的元素
res = [0]*len(num)
i = len(num) - 1
while i >= 0:
while len(stack) != 0 and stack[-1] <= num[i]: #如果栈不空而且栈顶还比当前元素小,出栈
stack.pop()
res[i] = -1 if len(stack) == 0 else stack[-1] #上一个循环结束后,如果栈中仍有元素,说明该栈顶比当前元素大,写入res相应位置,如果栈空,则写入-1
stack.append(num[i]) #入栈当前元素
i -= 1
return res[0:len(nums)] #最后返回和nums相同长度的res即可
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = dict(zip(nums2,[0]*len(nums2))) #存储nums2中每个元素对应的下一个更大
stack = []
i = len(nums2) - 1
ans = [] #答案数组
while i >= 0:
while len(stack) and stack[-1] <= nums2[i]:
stack.pop()
res[nums2[i]] = -1 if len(stack) == 0 else stack[-1]
stack.append(nums2[i])
i -= 1
for i in nums1:
ans.append(res[i]) #查表并插入答案中
return ans
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
answer = []
res = [0]*len(temperatures)
i = len(temperatures) - 1
stack = []
while i >= 0:
while len(stack) and temperatures[stack[-1]] <= temperatures[i]:
stack.pop()
res[i] = 0 if len(stack) == 0 else stack[-1] - i
stack.append(i) #将索引压入栈
i -= 1
return res
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
import collections
queue = collections.deque()
res = [0]*(len(nums)-k+1)
for i in range(len(nums)):
while queue and nums[queue[-1]] <= nums[i]: #如果队尾的数据小于当前数据,弹出
queue.pop() #右出,保证队尾一定是最大值
queue.append(i) #右边进队
if queue[0] <= i - k: #如果队头超出窗口边界了,左出
queue.popleft()#左出
if i - k >= -1: #绕过前k个值
res[i-k+1] = nums[queue[0]] #把队尾最大值写入res中
return res
该题目有三个要求:(1)去重,(2)顺序不变,(3)字典最小。
使用一个栈来存储遍历的数据,首先我们给字符串中出现的字符计数,然后遍历该字符串,每次遍历都给计数减一,如果该元素已经出现在栈中,就跳过,不操作。没有出现在栈中,我们要尽可能保证栈底是字典小的字符,所以,当元素小于栈顶时,并且后面还有该元素,就出栈该元素。
class Solution:
def removeDuplicateLetters(self, s: str) -> str:
count = [0]*256 #小写字母的ASCII码不会超过256
for i in s:
count[ord(i)] += 1 #ord(char)会将char的ASCII码返回
import collections
queue = collections.deque()
for j in range(len(s)):
count[ord(s[j])] -= 1 #每遍历一个字符就给相应的count减一
if s[j] in queue: #如果该元素已经在栈里了,忽略
continue
while queue and queue[-1] >s[j] and count[ord(queue[-1])] != 0:
queue.pop() #栈顶元素大于当前元素且该元素计数不为0,出栈
queue.append(s[j]) #入栈
ans = ''
while queue:
ans = ans + ans.join(queue.popleft()) #因为栈的底部是最小的,所以让底部先出
return ans
class Solution:
def smallestSubsequence(self, s: str) -> str:
count = [0]*256
for c in s:
count[ord(c)] += 1
import collections
queue = collections.deque()
ans = ''
for i in range(len(s)):
count[ord(s[i])] -= 1
if s[i] in queue:
continue
while queue and queue[-1] > s[i] and count[ord(queue[-1])] != 0:
queue.pop()
queue.append(s[i])
while queue:
ans = ans + ans.join(queue.popleft())
return ans