1、问题描述
给定两个没有重复元素的数组nums1和nums2,其中,nums1是nums2的子集,找到nums1中每个元素在nums2中下一个比它大的元素。
nums1中x在nums2中的下一个更大元素是指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、解题思路
- 思路1:这道题其实和leetcode - [栈] -(1)每日温度一样,每日温度求的是全集的下一个更大元素,而这道题求的是子集。所以,可以先求出全集的下一个更大元素,然后再从中找出子集的。和“每日温度”一样的做法,逆序遍历数组nums2,并使用栈维持一个非递增序列。初始化时,将nums2中最后一个元素的索引压入栈中,并将nextbigger数组中对应位置的值设置为-1,从nums2数组的倒数第二个数开始遍历,如果当前遍历元素大于等于栈顶元素,则将栈顶元素弹出直到栈顶元素大于当前遍历元素为止,若栈中元素全部弹出为空后,仍没有找到大于当前遍历元素的元素,则说明当前遍历元素没有下一个更大的元素,此时将nextbigger数组中对应位置的值设置为-1,如果栈中元素没有全部弹出,那么nextbigger数组中对应位置的值即为nums2中索引为栈顶元素所对应的元素。
- 分析它的时间复杂度,要从整体来看:总共有 n 个元素,每个元素都被 push 入栈了一次,而最多会被 pop 一次,没有任何冗余操作。所以总的计算规模是和元素规模 n 成正比的,也就是 O(n) 的复杂度。
3、代码实现
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
if len(nums1) == 0 or len(nums2) == 0:
return []
result = []
nextbigger = [0] * len(nums2)
stack = []
stack.append(len(nums2) - 1)
nextbigger[len(nums2) - 1] = -1
for i in range(1,len(nums2)):
ind = len(nums2) - 1 - i
while len(stack) != 0 and nums2[ind] >= nums2[stack[-1]]:
stack.pop()
if len(stack) != 0:
nextbigger[ind] = nums2[stack[-1]]
else:
nextbigger[ind] = -1
stack.append(ind)
for e in nums1:
index = nums2.index(e)
result.append(nextbigger[index])
return result