难度简单
给你两个 没有重复元素 的数组 nums1
和 nums2
,其中nums1
是 nums2
的子集。
请你找出 nums1
中每个元素在 nums2
中的下一个比其大的值。
nums1
中数字 x
的下一个更大元素是指 x
在 nums2
中对应位置的右边的第一个比 x
大的元素。如果不存在,对应位置输出 -1
。
思路:
采用单调栈方式将 nums2 数组中计算各元素右侧第一各比当前元素大的元素。
再次计算后可以很容易得到满足条件的结果。
单调栈 -> 栈内为单调元素,若当前元素不满足原有的单调性,将不满足的元素弹出栈,重构单调序列。
代码:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
int len1=nums1.size(),len2=nums2.size();
stack<int> s;
unordered_map<int, int> data;
vector<int> ans;
for(auto& index:nums2){
while(!s.empty() && index>s.top()){
data[s.top()]=index;
s.pop();
}
s.push(index);
}
while(!s.empty()){
data[s.top()] = -1;
s.pop();
}
for(auto& index:nums1){
ans.push_back(data[index]);
}
return ans;
}
难度中等277
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
思路:
根据下一个更大元素 Ⅰ 的思路,再次进行第二次计算,同时需要满足计算的元素应该为 该 元素的位置之前的元素。
代码:
vector<int> nextGreaterElements(vector<int>& nums) {
int len= nums.size();
stack<pair<int,int>> s;
vector<int> ans;
ans.resize(len);
for(int i=0;i<len;++i){
while(!s.empty() && nums[i]>s.top().first){
ans[s.top().second] = nums[i];
s.pop();
}
s.push({nums[i],i});
}
for(int i=0;i<len;++i){
while(!s.empty() && nums[i]>s.top().first && s.top().second > i){
ans[s.top().second] = nums[i];
s.pop();
}
}
while(!s.empty()){
ans[s.top().second] = -1;
s.pop();
}
return ans;
}