2454. 下一个更大元素 IV [Hard] 题解
Leetcode 2454. 下一个更大元素 IV
给你一个下标从 0 开始的非负整数数组
nums 。对于 nums
中每一个整数,你必须找到对应元素的 第二大 整数。
如果 nums[j] 满足以下条件,那么我们称它为
nums[i] 的 第二大 整数:
j > inums[j] > nums[i]- 恰好存在 一个
k满足i < k < j且nums[k] > nums[i]。
如果不存在 nums[j] ,那么第二大整数为 -1
。
- 比方说,数组
[1, 2, 4, 3]中,1的第二大整数是4,2的第二大整数是3,3和4的第二大整数是-1。
请你返回一个整数数组 answer ,其中
answer[i]是 nums[i] 的第二大整数。
示例 1:
1 | 输入:nums = [2,4,0,9,6] |
示例 2:
1 | 输入:nums = [3,3] |
提示:
1 <= nums.length <= 10^50 <= nums[i] <= 10^9
思路
一眼感觉就是单调栈的题目,但还是无脑树状数组
- 首先看范围:1e9? ==> 离散化一下。
- 如果是求下一个更大的元素,那直接从后往前依次添加到树状数组;查询时取下标最小值即可(由于树状数组维护的是前缀信息,所以离散化时需要将大小翻转一下)。
[2,4,0,9,6] ==> mp[9:1, 6:2, 4:3, 2:4, 0:5]
查询0时,已有数组a:[0, 3, 4, 0, 0, 0] (3,4分别是数字9和6在nums的下标)。
0对应大小为5,所以比它大的肯定存储在数组a[1-4]位置上。
利用树状数组求出这个a[1-4]中维护的下标最小值,得到结果:nums[3] = 9。
- 如果是求第二大的元素,那其实与上面类似,仍然用树状数组维护,但查询时每次要维护两个比当前元素大的值,且他们在nums中下标最小。最后取两个中下标较大的为答案。
[2,4,0,9,6] ==> mp[9:1, 6:2, 4:3, 2:4, 0:5]
查询2时,已有数组a:[0, 3, 4, 1, 0, 2] (3,4,1,2分别是数字9,6,4,0在nums的下标)。
2对应大小为4,所以比它大的肯定存储在数组a[1-3]位置上。
则此时需要用树状数组维护a[1-3]中下标最小的和次小的:分别是1,3。
所以最终nums[3]=9是nums[0]=2的第二大的值。
- 但有一个问题:如果有两个相同的数字呢?
树状数组同一个位置上要存储两个最小的下标
[2,4,4,6,4,4] ==> mp[6:1, 4:2, 2:3]
查询2时,已有数组a:[0, 3, {1,2,4,5}, 0] (3,{1,2,4,5}分别是数字6,4在nums的下标)。
2对应大小为3,所以比它大的肯定存储在数组a[1-2]位置上。
则此时需要用树状数组维护a[1-2]中下标中最小的和次小的。
即3 + {1,2,4,5} = {1,2,3,4,5} 中最小的和次小的
所以最终nums[2]=4是nums[0]=2的第二大的值。
可以发现对4维护的下标1,2,4,5中4和5都是无用的:因为如果一个数比4小,那么最后最终取最小和次小下标时,4和5是肯定不会选中的,所以每次只要维护两个最小值即可
代码
1 | class Solution { |
复杂度分析
- 时间:O(nlog n)。
- 空间:O(n)。