返回

攻克 LeetCode 496:下一刻更大的数字,稳操胜券!

闲谈

一、题目

496. 下一个更大元素 I

给你两个没有重复元素的数组 nums1 和 nums2 ,其中 nums1 是 nums2 的子集。

请你找出 nums1 中每个元素在 nums2 中的下一个更大元素。

nums1 中的下一个更大元素是指 找nums2中第一个比当前元素大的数 。如果没有,则返回 -1。

示例 1:

输入:nums1 = [4,1,2], nums2 = [1,3,4,2]
输出:[3,-1,-1]
解释:
- `4` 的下一个更大元素是 `3` 。
- `1` 的下一个更大元素是 `3` 。
- `2` 的下一个更大元素不存在,所以返回 `-1` 。

示例 2:

输入:nums1 = [2,4], nums2 = [1,2,3,4]
输出:[3,-1]
解释:
- `2` 的下一个更大元素是 `3` 。
- `4` 的下一个更大元素不存在,所以返回 `-1` 。

提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 104
  • nums1nums2 中的所有整数 互不相同
  • nums1 中的所有整数 均出现在 nums2

二、核心思想

解决本题的关键在于 单调栈 的运用。单调栈是一种数据结构,它允许我们以 O(1) 的时间复杂度查找和删除栈顶元素。通过使用单调栈,我们可以将 nums2 中的元素按 递减顺序 存储起来。这样,当我们遍历 nums1 时,对于每个元素 num,我们只需要在单调栈中找到第一个比 num 大的元素,即可得到 num 的下一个更大元素。如果单调栈中没有比 num 大的元素,则说明 num 没有下一个更大的元素,此时我们返回 -1

三、代码实现

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        # 使用栈来存储元素
        stack = []
        # 使用字典来存储元素及其下一个更大元素
        next_greater = {}
        
        # 遍历 nums2,将元素按递减顺序压入栈中
        for num in nums2:
            # 如果栈不为空,并且栈顶元素小于当前元素
            while stack and stack[-1] < num:
                # 将栈顶元素弹出,并将其下一个更大元素记录到字典中
                next_greater[stack.pop()] = num
            # 将当前元素压入栈中
            stack.append(num)
        
        # 遍历 nums1,并查找每个元素的下一个更大元素
        result = []
        for num in nums1:
            # 如果当前元素在字典中,则说明它有下一个更大的元素
            if num in next_greater:
                result.append(next_greater[num])
            # 否则,说明它没有下一个更大元素
            else:
                result.append(-1)
        
        # 返回结果
        return result

四、复杂度分析

  • 时间复杂度:O(n + m),其中 n 是 nums1 的长度,m 是 nums2 的长度。我们需要遍历 nums2 一次,将元素按递减顺序压入栈中,这需要 O(m) 的时间。我们还需要遍历 nums1 一次,并查找每个元素的下一个更大的元素,这需要 O(n) 的时间。因此,总的时间复杂度为 O(n + m)。
  • 空间复杂度:O(m),我们需要使用栈来存储 nums2 中的元素,这需要 O(m) 的空间。

五、总结

在本文中,我们详细讲解了如何使用单调栈解决 LeetCode 496:下一个更大元素 I 这一问题。我们首先对题目进行了分析,然后介绍了核心思想——单调栈,并提供了详细的代码实现。最后,我们对算法的复杂度进行了分析。希望本文能够帮助你轻松攻克这一挑战,在算法的道路上不断进步!