【栈-简单】496. 下一个更大元素 I(两种方法:单调栈,暴力法)

本文探讨如何在两个已排序数组nums1和nums2中,针对nums1中的每个元素高效找到其在nums2中的下一个大于自身的值,重点介绍暴力法和单调法两种方法,并展示如何通过单调性优化至O(nums1.length+nums2.length)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目】
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。
【示例 1】
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
对于 num1 中的数字 4 ,你无法在第二个数组中找到下一个更大的数字,因此输出 -1 。
对于 num1 中的数字 1 ,第二个数组中数字1右边的下一个较大数字是 3 。
对于 num1 中的数字 2 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
【示例 2】
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
【提示】
1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 104
nums1和nums2中所有整数 互不相同
nums1 中的所有整数同样出现在 nums2 中
进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?
【代码】
【Python】
【方法1:暴力法,不符合进阶要求】
在这里插入图片描述

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        pos=[-1]*10001
        for index,x in enumerate(nums2):
            pos[x]=index
        for index,x in enumerate(nums1):
            if pos[x]==len(nums2)-1:
                nums1[index]=-1
            else:
                flag=1
                for i in range(pos[x]+1,len(nums2)):
                    if nums2[i]>x:
                        flag=0
                        nums1[index]=nums2[i]
                        break
                if flag:
                    nums1[index]=-1
        return nums1

【方法2:单调法,满足进阶要求】
在这里插入图片描述

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        dic=dict()
        dic[nums2[0]]=-1
        s=[nums2[0]]
        for i in range(1,len(nums2)):
            while s and s[-1]<nums2[i]:
                dic[s[-1]]=nums2[i]
                s.pop()
            s.append(nums2[i])
        return [dic.setdefault(x,-1) for x in nums1]
<think>嗯,用户想了解单调栈的优点以及它在数据结构与算中的应用场景。首先,我需要回顾一下单调栈的基本概念。根据引用[1]和[2],单调栈是一种特殊的数据结构,内部元素保持单调递增或递减。那它的优点是什么呢?可能包括时间复杂度低,因为每个元素只入一次,所以是O(n)的时间复杂度。另外,它能高效解决特定问题,比如寻找下一个更大或更小的元素。 接下来应用场景方面,用户提到的引用里有一些例子,比如下一个更大元素、柱状图中的最大矩形等。需要把这些整理出来,可能需要分点说明。比如第一个应用是找到元素的下一个更大或更小元素,第二个是处理区间最值问题,第三个是计算面积相关的问题,比如接雨水或者最大矩形面积。 另外,用户可能需要知道为什么单调栈在这些场景下有效。比如,在寻找下一个更大元素时,维护一个单调递减,当遇到比顶大的元素时,就可以确定元素的下一个更大元素就是当前元素,这样就能快速处理。这利用了结构的后进先出特性,保持单调性后可以快速定位所需元素。 还有注意引用中的模板代码,比如引用[4]中的单调递增和递减的模板,可能需要解释一下这些模板的使用方法,但用户的问题是优点和应用场景,所以代码示例可能不需要详细展开,但可以简要提到。 需要确保回答的结构清晰,分点列出优点和应用场景,每个点下给出具体的例子或解释。同时,根据用户提供的引用,正确标注引用来源,比如在提到时间复杂度优势时引用[2],提到应用场景时引用[1]、[3]、[4]。 最后,生成的相关问题可能需要围绕单调栈的实现、与其他数据结构的比较、具体问题的解决方案等,比如如何实现单调栈,或者比较单调栈和普通的差异,或者具体的LeetCode题目应用。</think>### 单调栈的优势与应用场景 #### 一、单调栈的核心优势 1. **时间复杂度低** 单调栈的每个元素最多入和出一次,因此时间复杂度通常为 $O(n)$。例如,在寻找数组中每个元素的“下一个更大元素”时,单调栈能高效完成遍历和比较操作[^2]。 2. **空间复杂度可控** 的存储空间仅与输入规模线性相关,且可通过优化进一步减少空间占用(例如复用原数组)。 3. **简化复杂问题** 对于需要寻找特定顺序或区间极值的问题,单调栈通过维护单调性将问题分解为局部操作,例如快速定位某个元素左右两侧的边界[^1]。 --- #### 二、常见应用场景 1. **寻找“下一个更大/更小元素”** - **问题示例**:给定数组 $nums$,为每个元素找到右侧第一个比它大的元素- **实现方式**:使用单调递减。当新元素大于顶时,元素的下一个更大元素即为当前元素,随后弹出顶并记录结果[^4]。 2. **区间最值问题** - **典型问题**:滑动窗口最大值(LeetCode 239)。 - **实现方式**:使用单调递减队列(类似),维护窗口内的最大值候选集,确保队首始终为当前窗口最大值[^3]。 3. **面积或边界相关计算** - **柱状图中最大矩形(LeetCode 84)**:通过单调递增确定每个柱子左右第一个比它矮的边界,从而计算以该柱子为高度的最大矩形。 - **接雨水(LeetCode 42)**:通过单调递减找到左右边界,计算凹槽区域的储水量。 4. **数据压缩与预处理** 单调栈可用于将复杂序列转化为单调序列,简化后续处理步骤。例如,在动态规划问题中预处理某些约束条件。 --- #### 三、与其他数据结构的对比 | 场景 | 单调栈/队列 | 普通/队列 | |---------------------|-------------------------------|--------------------------| | 滑动窗口最大值 | 通过单调性维护候选集,$O(n)$ | 暴力遍历,$O(nk)$ | | 下一个更大元素 | 一次遍历即可完成,$O(n)$ | 嵌套循环,$O(n^2)$ | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值