【Leetcode】503. Next Greater Element II 503. 下一个更大元素 II

解法

解法一:栈

官方解答:https://leetcode.com/problems/next-greater-element-ii/solution/

其实找某个元素之后离它最近的比它大的元素用栈很好实现
维护一个栈,从后往前遍历数组,每遍历到一个新数时:

  1. 把栈顶小于等于这个数的元素都出栈
  2. 现在栈顶元素就是离它最近的比它大的数了
  3. 再把新数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

相关文章: