本章开始单调栈的内容。
739. 每日温度
本题翻译过来就是:找每一个元素从这个下标开始,第一个比他大的元素的下标,返回二者之间的距离。
单调栈的工作原理:
单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。
由于我们要求的是右侧第一个递增的元素,所以要维护一个从底部到顶部为递增到栈。
同时为了记录距离,需要同时伴随一个记录答案的数组。
1、比较栈顶下标所指向的元素和遍历到的元素大小,如果比遍历到的元素大,则将遍历到的元素放入栈中;
2、如果栈顶元素和遍历到的元素相等,则也将元素放入栈中;
stack.append(i) # 新元素的下标加入栈顶
3、如果栈顶元素小于遍历到的元素,则将两者索引的差值储存到结果集合中对应的栈顶元素的下标位置,同时弹出栈顶元素。重复以上过程,直到遍历到的元素比栈顶元素小,将遍历到的元素加入栈顶。
while stack and temperatures[i] > temperatures[stack[-1]]: # 当栈非空,并且当前栈顶下标所对应的气温小于当前遍历的气温
res[stack[-1]] = i - stack[-1] # 储存结果
stack.pop() # 弹出栈顶元素
class Solution(object):
def dailyTemperatures(self, temperatures):
"""
:type temperatures: List[int]
:rtype: List[int]
"""
res = [0] * len(temperatures) # 存放结果
stack = [] # 存放下标
for i in range(len(temperatures)):
while stack and temperatures[i] > temperatures[stack[-1]]: # 当栈非空,并且当前栈顶下标所对应的气温小于当前遍历的气温
res[stack[-1]] = i - stack[-1] # 储存结果
stack.pop() # 弹出栈顶元素
stack.append(i) # 新元素的下标加入栈顶
return res
496. 下一个更大元素 I
本题和上一个题目的区别在于需要在储存答案之前判断是否出现在另一个数组中,并且还需要查找出现的索引位置。
因为1是2的子集,所以在遍历的过程中,以2作为主要的遍历对象,同时在2中维护一个单调栈,在栈顶元素和1中一致的时候,查询这个元素在1中的位置,同时更新答案对应索引位置处的值为新遍历到的元素。
代码相当于在上一题的基础上加入了判断和取索引的过程。
class Solution(object):
def nextGreaterElement(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
res = [-1] * len(nums1)
stack = []
for i in range(len(nums2)):
while stack and nums2[i] > nums2[stack[-1]]:
if nums2[stack[-1]] in nums1: # 只有当nums2的元素出现在nums1中时,才会记录到res中,否则只是在nums2中维护一个单调栈
index1 = nums1.index(nums2[stack[-1]])
res[index1] = nums2[i]
stack.pop()
stack.append(i)
return res
503. 下一个更大元素 II
本题在温度的替代基础上加入了循环的要求,也就是数组的首尾相接。
为了不单独增加内存,这里不将nums进行扩充成2倍,而是采用模拟走两遍的方法进行遍历。
也就是遍历的index在range(len(nums) * 2),那么如何将index映射回对应在数组里的实际下标呢?
对len(nums)取余数即可,例如,在遍历到len(nums) + 1的时候,也就是实际上映射到了原来是数组的下标1处。
所以这里的index不是指实际上的数组下标,应该在单调栈维护的过程中使用[i % len(nums)]作为实际的下标。
class Solution(object):
def nextGreaterElements(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
res = [-1] * len(nums)
stack = []
for i in range(len(nums) * 2):
while stack and nums[i % len(nums)] > nums[stack[-1]]:
res[stack[-1]] = nums[i % len(nums)]
stack.pop()
stack.append(i % len(nums))
return res
Day53完结!!!