496. 下一个更大元素 I - 力扣(LeetCode) (leetcode-cn.com)
503. 下一个更大元素 II - 力扣(LeetCode) (leetcode-cn.com)
556. 下一个更大元素 III - 力扣(LeetCode) (leetcode-cn.com)
1
条件
1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 10^4
nums1和nums2中所有整数 互不相同
nums1 中的所有整数同样出现在 nums2 中
方法一 暴力
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
ans = [-1]*len(nums1)
d2 = dict()
for ind,val in enumerate(nums2):
d2[val] = ind
# 序号,值
for k,v in enumerate(nums1):
for j in range(d2[v]+1,len(nums2)):
if nums2[j] > v:
ans[k] = nums2[j]
break
return ans
方法二 单调栈
维护一个栈 s
和一个hashmapdct
先考虑 nums2
中的元素
对于 v in nums2
和栈顶元素 s[-1]
,如果栈顶元素不存在,即栈空,那么v
入栈
如果栈顶元素存在,考虑v
和s[-1]
的关系,首先v
和s
中的元素位置关系是:v是s中元素后面的元素,即v排在后面,那么如果v大于s[-1]
,意味着s[-1]
找到了一个大于它的元素,我们出栈,计dct[s[-1]] = v
,表示s[-1]
这个元素的下一个更大元素是v
对于栈中所有元素,我们重复执行上述步骤,直到栈为空或者s[-1]
大于等于v
,即v不是s[-1]
的下一个更大元素,那么v也不是s[-2, -3 ,...0]
中的更大元素
s实际上从栈底到栈顶保持一个单调不增的性质
最后我们遍历完nums2中的元素,如果s
中仍然有元素,那么我们出栈将它们的value设置为-1,表示并没有下一个更大的元素
想清楚上面的性质之后,我们就能写出这道题的答案了
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
ans = [-1]*len(nums1)
stack = []
dct = dict()
for v in nums2:
if len(stack) == 0:
stack.append(v)
else:
while len(stack)!=0 and stack[-1] < v:
dct[stack[-1]] = v
stack.pop()
stack.append(v)
while len(stack) != 0:
dct[stack[-1]] = -1
stack.pop()
for ind,val in enumerate(nums1):
ans[ind] = dct[val]
return ans
2
方法1 暴力
勉强通过
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
ans = [-1] * len(nums)
size = len(nums)
nums.extend(nums)
for i in range(size):
for k in range(i+1,i+size):
if nums[k] > nums[i]:
ans[i] = nums[k]
break
return ans
方法2 单调栈
还是用和第一问一样的思路,但是这道题多了重复元素+循环数组这两个因素,循环数组一个直观的方法就是nums.extend(nums)
,
考虑到重复元素,我们把对每个入栈的元素,记录它的下标,然后出栈的时候更新对应位置的值即可
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
s = []
ans = [-1] * len(nums)
size = len(nums)
nums.extend(nums)
# 注意循环范围
for i in range(len(nums)-1):
v = nums[i]
# 发现下一个更大的元素
while len(s) != 0 and s[-1][0] < v:
ans[s.pop()[1] % size] = v
# v 和 ind
s.append((v,i))
return ans
但我们不用真正的扩展一个数组,而是采用下标取余的方式即可
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
s = []
ans = [-1] * len(nums)
size = len(nums)
for i in range(2*size-1):
v = nums[i%size]
while len(s) != 0 and s[-1][0] < v:
ans[s.pop()[1] % size] = v
# v 和 ind
s.append((v,i))
return ans
更进一步的,我们优化入栈的元素结构,我们直接入栈下标,而不是元素
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
s = []
ans = [-1] * len(nums)
size = len(nums)
for i in range(2*size-1):
v = nums[i%size]
while len(s) != 0 and nums[s[-1]] < v:
ans[s.pop()] = v
# v 和 ind
s.append(i%size)
return ans
3
这道题和全排列的方法挂钩,生成全排列的方式不熟悉,先留着