下一个更大元素 123

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入栈
如果栈顶元素存在,考虑vs[-1]的关系,首先vs中的元素位置关系是: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

这道题和全排列的方法挂钩,生成全排列的方式不熟悉,先留着

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值