栈和队列的补充
1047.删除字符串中的所有相邻重复项
使用栈解决会很方便
class Solution:
def removeDuplicates(self, s: str) -> str:
res = []
for item in s:
if res and res[-1] == item:
# 如果res不为空且最后一个元素相等
res.pop()
else:
res.append(item)
return "".join(res)
150.逆波兰表达式求值
将题意理解后这道题也不是很难,和上道题倒是很相像
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for item in tokens:
if item not in {"+", "-", "*", "/"}:
stack.append(item)
else:
first_num, second_num = stack.pop(), stack.pop()
# 在python中的字符串前面加f,可以格式化{}中的内容
stack.append(int(eval(f'{second_num} {item} {first_num}'))) # 注意出栈入栈顺序,第一个出来的在运算符的后面
return int(stack.pop()) # 如果一开始只有一个数,那么会全部是字符串形式的
347.前K个高频元素
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
dic = {}
for i in range(len(nums)):
if nums[i] not in dic:
dic[nums[i]] = 1
else:
dic[nums[i]] += 1
l = list(dic.items())
l.sort(key= lambda x:x[1], reverse=True)
res =[]
for i in range(k):
res.append(l[i][0])
return res
单调栈的学习
739.每日温度
暴力求解的话,是两层的for循环,时间复杂度是n^2
通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈。
例如本题其实就是找到一个元素右边第一个比自己大的元素,自然是选用单调栈了。
单调栈的时间复杂度是n,其实本质上是一种空间换时间的方法,遍历的过程中使用额外栈记录右边第一个比当前元素大的元素,优点是只需要遍历一次。
单调栈基础
单调栈里存放的元素:单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素直接T[i]就可以获得。
单调栈内是递增还是递减?注意一下顺序为从栈头到栈底,此基础上使用递增的顺序,因为只有递增的时候,加入一个元素i,才知道栈顶元素在数组中右边第一个比栈顶元素大的元素是i。
使用单调栈主要有三个判断条件:当前遍历的元素T[i]小于这栈顶元素T[st.top()]的情况。当前遍历的元素T[i]等于这栈顶元素T[st.top()]的情况。当前遍历的元素T[i]大于这栈顶元素T[st.top()]的情况。
当前遍历的元素T[i]大于这栈顶元素T[st.top()]。则st弹出栈顶元素,加入i,answer数组计算
当前遍历的元素T[i]小于等于这栈顶元素T[st.top()]。则st将i压栈
代码
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
answer = [0]*len(temperatures)
stack = [0]
for i in range(1,len(temperatures)):
# 情况一和情况二
if temperatures[i]<=temperatures[stack[-1]]:
stack.append(i)
# 情况三
else:
while len(stack) != 0 and temperatures[i]>temperatures[stack[-1]]:
answer[stack[-1]]=i-stack[-1]
stack.pop()
stack.append(i)
return answer
496.下一个更大的元素I
需要熟练使用单调栈
503.下一个更大元素II
需要熟练使用单调栈