Next Greater Element--关于栈的妙用

Next Greater Element–关于栈的妙用

标签(空格分隔): Leetcode 数据结构


  近来在复习Leetcode上的经典题目时,发现有些题目借助栈这个简单的数据结构,能有非常巧妙地解法,直接让时间复杂度从 O(n2) O ( n 2 ) 下降到 O(n) O ( n ) ,让人惊叹不已,算法的世界真是太奇妙了!废话少说,直接上题,这里直接给出Next Greater Element Π Π 的题目和解答思路, I I  的话思路相仿,是简化版本,故略去不提。

原题描述:

  Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn’t exist, output -1 for this number.
  给出一个循环数组,打印出比每一个元素大的“下一个数”,“下一个数”指的是按照顺序(从该元素起往后查找,遇到最后一个元素后从数组头开始,直至再次到达自己位置结束)查找到的第一个大于该元素的数,如果没有则输出-1。这里有一个示例:

Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1’s next greater number is 2; The number 2 can’t find next greater number; The second 1’s next greater number needs to search circularly, which is also 2.

  一般的思路就是顺序依次搜索从当前元素索引到数组尾部、数组头部到当前元素索引的所有元素,这样的话时间复杂度是 O(n2) O ( n 2 ) ,  n n 为数组长度。一种利用栈的巧妙方法是,从数组尾部向头部开始搜索,用栈来维护所有大于当前元素的元素索引,即对于当前元素,如果栈顶索引代表的元素小于该元素,弹出该索引,否则找到该元素的Next Greater Element. 如果栈空,则Next Greater Element为-1。对于在该元素左边的情况,再次重复上述过程(保持栈不变)即可。这样只需要遍历两次数组,同时每个元素的入栈出栈次数都为1,因此时间复杂度仅为 O(n) O ( n ) . 动态图的描述如下:

第一轮:

Next Greater Element--关于栈的妙用_第1张图片

第二轮:

Next Greater Element--关于栈的妙用_第2张图片

代码:

class Solution:
    def nextGreaterElements(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        stack = []
        res = [0]*len(nums)
        for j in range(2):
            for i in range(len(nums)-1, -1, -1):
                curr = nums[i]
                while len(stack) != 0 and curr >= nums[stack[-1]]:
                    stack.pop()
                if len(stack) == 0:
                    res[i] = -1
                else:
                    res[i] = nums[stack[-1]]
                stack.append(i)
        return res

你可能感兴趣的:(leetcode,算法)