一但要求下一个更大的元素,就是用单调栈解更好
这个题考虑nums1中对应的nums2相同元素的后面寻找值更大的数
相当于是遍历nums2后面的元素 寻找大于nums1[i]的数字并保留
模式识别:【后入先出】>>>>栈
模式识别:求前/后的第一个最大/小元素 >>>>>单调栈
通常是一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素,且要求 O(n) 的时间复杂度
解法1 究极复杂法
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
result = []
for i in range(len(nums1)):
for j in range(len(nums2)): #遍历
if nums1[i]==nums2[j]: #找nums1[i]==nums2[j]
if j == len(nums2)-1 and nums2[j]<=nums1[i]:
result.append(-1)
else:
for p in range(1,len(nums2)-j):
if j+p <= len(nums2)-1: #j存在
if nums2[j+p]>nums1[i]:
result.append(nums2[j+p])
break
elif nums2[j+p]<=nums1[i] and p==len(nums2)-j-1:
result.append(-1)
break
else:
result.append(-1)
break
j = 0
break
return result
解法2 用两个栈去做
用两个栈 nums2入栈,弹出的元素入temp栈保存,之后重复上述过程
# 遍历nums1,之后nums2出栈比对大小 top = stack.pop()和nums1[i]
# 若相等则停止出栈,恢复temp中的元素到stack内,
# 若top>nums1[i],则令max = top,继续寻找
# 若top<nums1[i],则继续寻找
# 最终遍历结束 输出max的list即可
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
# time complexity O(MN)
# space complexity O(2N)=O(N)
# 用两个栈 nums2入栈,弹出的元素入temp栈保存
# 遍历nums1,之后nums2出栈比对大小 top = stack.pop()和nums1[i]
# 若相等则停止出栈,恢复temp中的元素到stack内,
# 若top>nums1[i],则令max = top,继续寻找
# 若top<nums1[i],则继续寻找
# 最终遍历结束 输出max的list即可
max = -1
final = []
stack = []
temp = []
for i in nums2:
stack.append(i) #nums2中的元素入栈
for num in nums1:
while len(nums2)!=0:
temnum = stack.pop() #nums2元素出栈
temp.append(temnum) #temnum入栈temp保存
if temnum==num: # 相等停止出栈 遍历下一个num1
break
elif temnum > num: # temnum大于num 保存max
max = temnum
else: # temnum小于num 不执行操作
continue
final.append(max)
max = -1
for m in range(len(temp)):
stack.append(temp.pop())
return final
解法3 暴力解法
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
m,n = len(nums1),len(nums2)
result = [0]*m
for i in range(m):
j = nums2.index(nums1[i]) # 寻找nums2中和nums1相同元素的index 【nums1是nums2的子集】
k = j+1
while k<n and nums2[k]<nums2[j]: # 当k小于len(nums2) and nums2[k]<nums2[j]=nums1[i]时 再向→找下一个
k +=1
result[i] = nums2[k] if k<n else -1
return result
解法4 单调栈☆
单调递增栈:从 栈底 到 栈顶 递增,栈顶大
单调递减栈:从 栈底 到 栈顶 递减,栈顶小
# nums2 →遍历 存每个元素右边第一个最大值进哈希表
# 方法:维护单调【递减】栈(栈底>>>栈顶,大>>>小,从而找到右边第一个比自己大的元素)
# 维护单调递减栈:1)遇到[当前元素] 大于 [栈顶元素top = stack.pop()] 时: 栈顶元素出栈,当前元素进栈
# 2)遇到[当前元素] 小于 [栈顶元素top = stack.pop()] 时:[当前元素]压入栈
# 3)最终清算栈内仍然留存的元素 赋-1(右边没有比这些元素的大的了)
# nums1中对应的nums2的元素 查哈希表 输出
# time complexity O()
# space complexity O()
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = {}
stack = []
# a = []
for num in nums2:
while stack and num > stack[-1]: # 当前元素大于栈顶元素时且栈内还有元素时: 弹出栈顶元素>>记录信息>>当前元素入栈
top = stack.pop() # 弹出栈顶元素
res[top] = num # 生成哈希表 key:元素 value:右边第一个最大的数值
stack.append(num) # 入栈
while stack: # 如果stack中还有元素 >>>弹出至空为止
res[stack.pop()] = -1 # 生成哈希表 key:元素 value:-1
return [res[num] for num in nums1] # 遍历nums1 从之前nums2生成出来的哈希表中寻找对应key的结果,并合并为列表输出【好方法】
结尾方法2【最好】
return [res.get(x, -1) for x in nums1]
结尾方法3
for n in nums1: # 遍历nums1 从之前nums2生成出来的哈希表中寻找对应key的结果,并合并为列表输出 【方法二】
a.append(res[n])
return a
寻找右边第一个最大的数
# 当前项向 右 找第一个比自己大的位置 —— 从左向右 维护一个单调递 减 栈
def nextGreaterElement(nums):
stack = []
res = {i: -1 for i in nums}
for num in nums:
while stack and num > stack[-1]: # 当前元素大于栈顶元素时且栈内还有元素时: 弹出栈顶元素>>记录信息>>当前元素入栈
top = stack.pop() # 弹出栈顶元素
res[top] = num # 生成哈希表 key:top 元素 value:num 右边第一个最大的数值
stack.append(num) # 当前元素入栈
return res
寻找右边第一个最小的数
# 当前项向 右 找第一个比自己小的位置 —— 从左向右 维护一个单调递 增 栈
def nextGreaterElement(nums):
stack = []
res = {i: -1 for i in nums}
for num in nums:
while stack and num < stack[-1]: # 当前元素小于栈顶元素时且栈内还有元素时: 弹出栈顶元素>>记录信息>>当前元素入栈
top = stack.pop() # 弹出栈顶元素
res[top] = num # 生成哈希表 key:top 元素 value:num 右边第一个最小的数值
stack.append(num) # 当前元素入栈
return res
寻找左边第一个最大的数
# 当前项向 左 找第一个比自己大的位置 —— 从右向左 维护一个单调递 减 栈
def nextGreaterElement(nums):
stack = []
res = {i: -1 for i in nums}
for num in reversed(nums): # 从右向左
while stack and num > stack[-1]: # 当前元素大于栈顶元素时且栈内还有元素时: 弹出栈顶元素>>记录信息>>当前元素入栈
top = stack.pop() # 弹出栈顶元素
res[top] = num # 生成哈希表 key:top 元素 value:num 左边第一个最大的数值
stack.append(num) # 当前元素入栈
return res
寻找左边第一个最小的数
# 当前项向 左 找第一个比自己小的位置 —— 从右向左 维护一个单调递 增 栈
def nextGreaterElement(nums):
stack = []
res = {i: -1 for i in nums}
for num in reversed(nums): # 从右向左
while stack and num < stack[-1]: # 当前元素小于栈顶元素时且栈内还有元素时: 弹出栈顶元素>>记录信息>>当前元素入栈
top = stack.pop() # 弹出栈顶元素
res[top] = num # 生成哈希表 key:top 元素 value:num 左边第一个最小的数值
stack.append(num) # 当前元素入栈
return res
nums = [4, 3, 5, 1, 2, 6]
result = nextGreaterElement(nums)