学习资料:https://programmercarl.com/0739.每日温度.html#算法公开课
单调栈:
用数组模拟单调栈,今天的题中,栈中元素都保存的索引值
基本思路:将新元素和栈顶索引对应值比较,如果要保持单调递增,则需要新元素不大于栈顶索引对应值;若满足就加入新元素索引到栈中;若不满足,就根据具体题意看是否找到目标值了,然后通过循环不断弹出栈顶值,知道新元素不大于栈顶值了,就把新元素索引加到栈中
循环数组:
当遇到循环数组问题,可以取模法:索引范围*2,再对每个索引取模 i%len(nums)
学习记录:
739.每日温度(单调栈;单调递增)
点击查看代码
class Solution(object):
def dailyTemperatures(self, temperatures):
"""
:type temperatures: List[int]
:rtype: List[int]
"""
# 单调栈解法,本题设定为递增,栈顶到栈底值越来越大(难点:栈中存放的是数的索引)
# 先初始化结果数组,默认没有更高温度的出现
answer = [0]*len(temperatures) # 当后面几天没有更高温度时也不用处理了,因为本来初值就定为0了
# 构建一个单调栈,还是数组的形式
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.下一个更大元素1(单调栈变形;当新元素大于栈顶索引对应值时,还得判断栈顶索引对应值是否是nums1中的元素,如果是,则找到目标值,即nums1在nums2中的更大值即为新元素)
点击查看代码
class Solution(object):
def nextGreaterElement(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
# 单调栈,特别之处:如果nums2的栈顶值<nums2遍历到的当前值,再判断栈顶值在不在nums1里面,如果在,就说明找到了nums1中数字的在nums2中的下一个更大元素
# 构造单调栈
stack = [0] # 栈中保存的是索引!!!!!!!!!!!!!
# 结果的保存,初值都设置为-1
ans = [-1]*len(nums1)
# 遍历nums2
for i in range(1, len(nums2)):
if nums2[stack[-1]] >= nums2[i]:
stack.append(i)
else:
while len(stack) != 0 and nums2[stack[-1]]<nums2[i]: # 防止空栈;当新元素大于栈顶元素
# 看栈顶元素是否在nums1中,如果在,就说明找到了nums1对应元素的下一个更大值,也就是新元素
if nums2[stack[-1]] in nums1:
# 保存结果
index = nums1.index(nums2[stack[-1]])
ans[index] = nums2[i]
# 不管怎样都要弹出栈顶,保证单调递增
stack.pop()
# 当新元素不大于栈顶值时,向单调栈加入新元素
stack.append(i)
return ans
503.下一个更大元素2(单调栈+循环数组)
点击查看代码
class Solution(object):
def nextGreaterElements(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# 单调栈+环形数组问题
# 当遇到环形数组,
# 法一:扩展数组为其二倍,如[2,3,4]变成[2,3,4,2,3,4]
# 法二: 索引取模法,for i in range(len(nums)*2): 后续中用i%len(nums),这样保证索引值一直是0,1,2
# 构建单调栈,保存索引值
stack = [0]
# 构建结果数组
result = [-1]*len(nums)
# 开始2倍遍历
for i in range(len(nums)*2):
# 对索引取模
i_mod = i%len(nums)
# 新元素不大于栈顶值,满足单调递增
if nums[i_mod] <= nums[stack[-1]]:
stack.append(i_mod) # 记住栈中保存的是索引
else:
# 开始循环,一直到新元素不大于栈顶值位置
while len(stack) != 0 and nums[i_mod] > nums[stack[-1]]:
# 收集结果
result[stack[-1]] = nums[i_mod] # 栈顶值的下一个更大元素是nums[i_mod]
# 弹出当前已经收集了结果的栈顶值
stack.pop()
# 加入新元素
stack.append(i_mod)
return result
PS:今天阴转小雨,不冷;周五吃的很随意,排骨面,自选菜,味道都一般,但是吃得饱;很累啊,论文有了新进展,理清了行文思路;
这周没有找工作进展,是等待的一周,希望下周等到机会~