Next Greater Element IV(附带个人感想)
Next Greater Element IV
You are given a 0-indexed array of non-negative integers nums . For each integer in nums , you must find its respective second greater integer.
The second greater integer of nums[i] is nums[j] such that:
- j > i
- nums[j] > nums[i]
- There exists exactly one index k such that nums[k] > nums[i] and i < k < j .
If there is no such nums[j] , the second greater integer is considered to be -1 .
- For example, in the array $[1, 2, 4, 3]$, the second greater integer of $1$ is $4$, $2$ is $3$, and that of $3$ and $4$ is $-1$.
Return an integer array answer , where answer[i] is the second greater integer of nums[i] .
Example 1:
Input: nums = [2,4,0,9,6] Output: [9,6,6,-1,-1] Explanation: 0th index: 4 is the first integer greater than 2, and 9 is the second integer greater than 2, to the right of 2. 1st index: 9 is the first, and 6 is the second integer greater than 4, to the right of 4. 2nd index: 9 is the first, and 6 is the second integer greater than 0, to the right of 0. 3rd index: There is no integer greater than 9 to its right, so the second greater integer is considered to be -1. 4th index: There is no integer greater than 6 to its right, so the second greater integer is considered to be -1. Thus, we return [9,6,6,-1,-1].
Example 2:
Input: nums = [3,3] Output: [-1,-1] Explanation: We return [-1,-1] since neither integer has any integer greater than it.
Constraints:
$1 <= nums.length <= {10}^{5}$
$0 <= nums[i] <= {10}^{9}$
解题思路
换一种思路来考虑找到第二大的数。对 nums 降序排序,然后从左开始枚举(即从最大的数开始枚举),每枚举到一个数就在该数原来所对应的下标位置进行标记。
比如对于样例一,排序后得到数组$[9, 6, 4, 2, 0]$,从左往右枚举,当我们枚举到$9$,就在下标为$4$的位置进行标记($9$原本在数组第$4$个下标位置),然后枚举到$6$,那么在下标为$5$的位置进行标志,以此类推。
当我们枚举到某个数,在原数组中对应的下标为$k$,现在我们要看它右边第二个比它大的数是哪个。因为比这个数大的数再前面已经枚举过了,因此比它大的数都已经被标记到数组中,因此要找到第二个比它大的数就是找到$k$右边第二个被标记的位置。
因此我们可以用一个std::set来维护所有被标记的下标位置,然后通过std::set::upper_lower()来找到第一个比$k$大的下标位置,然后再通过迭代器往后迭代一次得到第二个比$k$大的下标位置。
AC代码如下:
1 class Solution { 2 public: 3 vector<int> secondGreaterElement(vector<int>& nums) { 4 int n = nums.size(); 5 vector<int> p; 6 for (int i = 0; i < n; i++) { 7 p.push_back(i); 8 } 9 sort(p.begin(), p.end(), [&](int a, int b) { 10 return nums[a] > nums[b]; 11 }); 12 13 set<int> st; 14 st.insert(n), st.insert(n + 1); // 加哨兵,保证每个数都能找到第二个比它大的数 15 vector<int> ans(n, -1); 16 for (int i = 0; i < n; i++) { 17 // 如果遇到一段连续相同的数,需要一次性处理掉 18 int j = i + 1; 19 while (j < n && nums[p[j]] == nums[p[i]]) { 20 j++; 21 } 22 23 for (int k = i; k < j; k++) { 24 int x = *++st.upper_bound(p[k]); // 找到第二个比它大的数 25 if (x < n) ans[p[k]] = nums[x]; // 如果存在那么下标位置应该满足x<n 26 } 27 for (int k = i; k < j; k++) { 28 st.insert(p[k]); // 最后才把这一段连续的数的下标插入集合中 29 } 30 i = j - 1; 31 } 32 return ans; 33 } 34 };
感想
这可能是我近期最后一篇博客了。最近状态突然变得很差,什么做题都没有思路。大概从上上个星期开始吧,不知道是能力不够,还是说到了所谓的低谷期,比赛的rank一直不是很理想。从上个星期开始,甚至直接题都做不出来了,昨天有一场时长$2:45$的比赛,$9$道题,我只写出了第一题,真就罚坐了$2$个多小时,只做出最简单的一题,那种心态已经炸没了(直接掉了$100$多分,前面几场比赛全白打了)。今天早上吧,去打最简单的lc,结果又卡在第$2$题(前几次比赛都在第$2$卡了下),提交的代码一直Wrong Answer,后面心态直接炸了,最后十几分钟才冷静下来换了个做法才过了,排名直接掉到快$2k+$。学了快一年了,难题基本做不出来,不知道为什么现在连简单题都不会了。经常卡在一些偏脑筋急转弯的思维和贪心题。前几天,我拿个比赛时一小时没想出来的思维题跑去问一个完全没有学过算法的人,结果人家不到半小时就给出正确思路了。看来我真的成睿智了已经什么都不会了,简单题都已经不敢写了,生怕想不出来,之前的努力全部都是徒劳一样。现在直接什么都不想干,有种说不出的心情和感觉。至少半个月内我都不会写算法题了,现在对自己很是失望。尝试休息一下做点其他事情吧。
参考资料
LeetCode 2454. 下一个更大元素 IV(杂题选讲):https://www.acwing.com/video/4511/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16841590.html