3妹:“太陽當空照,花兒對我笑,小鳥說早早早,你為什么背上炸藥包”
2哥 :3妹,什么事呀這么開發。
3妹:2哥你看今天的天氣多好啊,陽光明媚、萬里無云、秋高氣爽,適合秋游。
2哥:是啊,立冬之后天氣多以多云為主,好不容易艷陽高照。可是你不能秋游,趕緊收拾收拾上班去啦
3妹:哼, 好吧~
2哥:給你出了一道題發你微信里了, 上班通勤的路上記得看一下,回來問你答案~
3妹:知道啦,難不倒我!
題目:
給你一個下標從 0 開始的非負整數數組 nums 。對于 nums 中每一個整數,你必須找到對應元素的 第二大 整數。
如果 nums[j] 滿足以下條件,那么我們稱它為 nums[i] 的 第二大 整數:
j > i
nums[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:
輸入:nums = [2,4,0,9,6]
輸出:[9,6,6,-1,-1]
解釋:
下標為 0 處:2 的右邊,4 是大于 2 的第一個整數,9 是第二個大于 2 的整數。
下標為 1 處:4 的右邊,9 是大于 4 的第一個整數,6 是第二個大于 4 的整數。
下標為 2 處:0 的右邊,9 是大于 0 的第一個整數,6 是第二個大于 0 的整數。
下標為 3 處:右邊不存在大于 9 的整數,所以第二大整數為 -1 。
下標為 4 處:右邊不存在大于 6 的整數,所以第二大整數為 -1 。
所以我們返回 [9,6,6,-1,-1] 。
示例 2:
輸入:nums = [3,3]
輸出:[-1,-1]
解釋:
由于每個數右邊都沒有更大的數,所以我們返回 [-1,-1] 。
提示:
1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
思路:
單調棧 + 優先隊列,
我們可以考慮將原始問題簡化為計算數組中每個數字的下一個比它大的數字。為了解決這一問題,我們可以利用「單調棧」算法。該算法的核心思想是利用一個棧來存儲數組元素的下標。在遍歷數組時,對于每個元素,執行以下操作:如果當前元素大于棧頂元素對應的值,說明找到了棧頂元素的下一個更大的數字,將棧頂元素出棧,并更新結果數組。如果當前元素小于等于棧頂元素對應的值,將當前元素的下標壓入棧中,保持棧的單調遞減性質。這樣,最終結果數組中存儲的就是每個數字的下一個比它大的數字(如果存在的話),如果沒有更大的數字,則對應位置的值為 ?1。
java代碼:
class Solution {public int[] secondGreaterElement(int[] nums) {int length = nums.length;int[] secondGreater = new int[length];Arrays.fill(secondGreater, -1);Deque<Integer> stack = new ArrayDeque<Integer>();PriorityQueue<int[]> pq = new PriorityQueue<int[]>((a, b) -> a[1] - b[1]);for (int i = 0; i < length; i++) {int num = nums[i];while (!pq.isEmpty() && pq.peek()[1] < num) {int index = pq.poll()[0];secondGreater[index] = num;}while (!stack.isEmpty() && nums[stack.peek()] < num) {int index = stack.pop();pq.offer(new int[]{index, nums[index]});}stack.push(i);}return secondGreater;}
}