解法
解法一:栈
官方解答:https://leetcode.com/problems/next-greater-element-ii/solution/
其实找某个元素之后离它最近的比它大的元素用栈很好实现
维护一个栈,从后往前遍历数组,每遍历到一个新数时:
- 把栈顶小于等于这个数的元素都出栈
- 现在栈顶元素就是离它最近的比它大的数了
- 再把新数push进去
循环数组与非循环的区别在于,循环数组在栈不重新设置的情况下遍历两次就好了:
class Solution(object):
def nextGreaterElements(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
from collections import deque
right = deque()
n = len(nums)
res = [-1]*n
for i in xrange(n-1,-1,-1):
while right and nums[right[-1]]<=nums[i]:
right.pop()
if right:
res[i] = nums[right[-1]]
right.append(i)
for i in xrange(n-1,-1,-1):
while right and nums[right[-1]]<=nums[i]:
right.pop()
if right and res[i]==-1:
res[i] = nums[right[-1]]
right.append(i)
return res
解法二:优化第二轮
我是想着先找每个数后面离它最近的大于它的值
然后对于那些还标成-1的数,再找这些数前面离他最远的大于它的值
前者用栈可以做。
注意到,还标成-1的数是后面没有比它更大的数的数,那么它们在数组里肯定是从左到右递减的
我们从右往左遍历这些-1的位置(就是从小到大),然后维护一个指针i,然后找到第一个使得nums[i]大于当前数的i
由于下一个数一定比当前数大,那么i前面的数一定没有用了,所以继续增大i即可,直到所有-1都遍历完成,或者i已经到达当前数的位置了
class Solution(object):
def nextGreaterElements(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
from collections import deque
right = deque()
n = len(nums)
res = [-1]*n
pending = deque()
for i in xrange(n-1,-1,-1):
while right and nums[right[-1]]<=nums[i]:
right.pop()
if right:
res[i] = nums[right[-1]]
else:
pending.append(i)
right.append(i)
i = 0
while pending and i<pending[0]:
while i<pending[0] and nums[i]<=nums[pending[0]]:
i += 1
if i<pending[0]:
res[pending.popleft()] = nums[i]
return res