[每日一題]Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II
2021/3/6
今天的每日一題是Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II,因為是同類型的題所以就放一塊寫了。
Leetcode496. 下一個更大元素 I題意:
給你兩個 沒有重複元素 的陣列 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
請你找出 nums1 中每個元素在 nums2 中的下一個比其大的值。
nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 x 大的元素。如果不存在,對應位置輸出 -1 。
首先看到這道題的第一思路肯定是暴力硬解,但是我們要思考除了暴力還有沒有別的思路呢?
我們考慮如下情況:有陣列[4,3,2,1,5],我們計算4,3,2,1這些元素的時候因為後一個數比前一個數小,所以我們都要等大於它們的數出現。當5出現的時候4,3,2,1這幾個數的後一個最大元素都是5,所以我們可以先不急著找比它們大的數,當比它們大的數出現的時候再統一處理。顯然我們可以考慮用一個棧來把它們存下來,這就是單調棧(單調棧是說棧裡面的元素從棧底到棧頂是單調遞增或者單調遞減的)。
當我們遍歷時會出現以下幾種情況:
1.棧為空,那麼就直接入棧。
2.如果當前元素比棧頂元素大:說明當前元素是前面一些元素的「下一個更大元素」,則逐個彈出棧頂元素,直到當前元素比棧頂元素小為止。
3.如果當前元素比棧頂元素小:說明當前元素的「下一個更大元素」與棧頂元素相同,則把當前元素入棧。
這一題我們可以先求出所有nums2中元素的下一個更大元素,因為沒有重複元素所以可以使用一個map對映到nums1中來減少複雜度。
c++參考程式碼:
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> st;
map<int,int> mp;
int n=nums2.size();
for(int i=0;i<n;i++)
{
while(!st.empty()&&nums2[i]>st.top())
{
mp[st.top()]=nums2[i];
st.pop();
}
st.push(nums2[i]);
}
while(!st.empty())//注意最大值的下一最大元素是-1
{ //最大值會一直在棧中所以需要最後處理
mp[st.top()]=-1;
st.pop();
}
vector<int> ans;
for(int i=0;i<nums1.size();i++)
{
ans.push_back(mp[nums1[i]]);
}
return ans;
}
};
![[每日一題]Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II [每日一題]Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II](https://img.796t.com/res/2021/03-08/15/6b53039774f76f370c0ae1432ae82bad.png)
Leetcode503. 下一個更大元素 II題意:
給定一個迴圈陣列(最後一個元素的下一個元素是陣列的第一個元素),輸出每個元素的下一個更大元素。數字 x 的下一個更大的元素是按陣列遍歷順序,這個數字之後的第一個比它更大的數,這意味著你應該迴圈地搜尋它的下一個更大的數。如果不存在,則輸出 -1。
和上一題一樣也是單調棧問題,但是不同的是題目說給出的陣列是迴圈陣列,何為迴圈陣列?就是說陣列的最後一個元素下一個元素是陣列的第一個元素,形狀類似於環。
我們可以把陣列複製一份到陣列末尾,這樣雖然不是嚴格的迴圈陣列,但是對於本題已經足夠了,因為本題對陣列最多遍歷兩次。然後再使用使用取模運算,可以把下標 i 對映到陣列 nums 長度的 0 - N內。
c++參考程式碼:
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
stack<int> st;
int n=nums.size();
vector<int> ans(n,-1);
for(int i=0;i<n*2-1;i++)
{
while(!st.empty()&&nums[i%n]>nums[st.top()])
{
ans[st.top()]=nums[i%n];
st.pop();
}
st.push(i%n);
}
return ans;
}
};
![[每日一題]Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II [每日一題]Leetcode496. 下一個更大元素 I和Leetcode503. 下一個更大元素 II](https://img.796t.com/res/2021/03-08/15/32ca0b0fddbd38d774b01bf16d780876.png)
參考資料
·負雪明燭《動畫講解:單調棧》
