问题描述:
思路:
这道题题目都读了半天才明白,翻译的实在有点...
暴力:遍历nums1的元素,每一轮遍历,在nums2中找到相同值的那个元素在nums2中的下标,从该下标开始遍历,遍历nums2数组,找到第一个比该元素值大的元素,加入到结果数组中,如果没有找到就加入-1。
单调栈法:单调栈的原理参考:https://blog.csdn.net/weixin_42784951/article/details/88963758; 开始时不需要管nums1,只需要对nums2构造单调栈,同时还要维护一个map。
单调栈在本题的规则:
① 栈中没有元素时可直接加入。
② 栈中有元素时,将加入的元素同栈顶元素比较
(1)如果比栈顶元素小,则入栈;
(2)如果比栈顶元素大,则将栈顶pop,同时建立栈顶元素与欲加入元素的map映射:map[stack[top]] = nums2[i]; ; 同时要注意如果栈顶pop后的新栈顶依然比欲加入元素小,则继续建立map映射:map[stack[top]]=nums2[i];,直到新的栈顶元素比欲加入的元素值大为止;
(3)不可能出现要加入的值和元素值相同的情况所以不考虑。
在对nums2所有元素构造完单调栈和map映射后,要注意要判断最后栈是否为空,如果栈不为空,那么还要将剩下的元素与-1分别映射,表示其后已经没有比他更大的元素了。
明显map映射构造的就是nums2数组中每个元素对应的 "之后比其大的第一个元素值",如果不存在就是与-1映射。
map映射建立完后,对nums1数组遍历,利用刚才的映射关系就可以轻松拿到值了。
坑:注意对vector数组erase以后,一定要注意遍历下标的i一定要i--处理,不然会跳过下一个元素还很不容易发现错误。
代码实现:
暴力:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
int i, j, n2_pointer;
for (i = 0; i < nums1.size(); i++) {
for (n2_pointer = 0; n2_pointer < nums2.size(); n2_pointer++) {
if (nums2[n2_pointer] == nums1[i]) {
break;
}
}
for (j = n2_pointer; j < nums2.size(); j++) {
if (nums2[j] > nums1[i]) {
ans.push_back(nums2[j]);
break;
}
if (j == nums2.size() - 1) {
ans.push_back(-1);
}
}
}
return ans;
}
单调栈:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
if (!nums1.size() && !nums2.size()) return ans;
vector<int> stack;
map<int, int> m;
stack.push_back(nums2[0]);
int top = 0;
for (int i = 1; i < nums2.size(); i++) {
if (nums2[i] > stack[top]) { // 如果比栈顶元素大,
m[stack[top]] = nums2[i]; // 建立栈顶元素与欲加入元素的map映射
nums2.erase(nums2.begin() + top); //栈顶pop
i--; // erase后一定要i--
top--;
while (top >= 0 && stack[top] < nums2[i]) {
// 同时要注意如果栈顶pop后的新栈顶依然比欲加入元素小,则继续建立map映射:map[stack[top]]=nums2[i];,直到新的栈顶元素比欲加入的元素值大为止;
m[stack[top]] = nums2[i];
nums2.erase(nums2.begin() + top);
i--; // erase后一定要i--
top--;
}
top++;
stack[top] = nums2[i];
}
else if (nums2[i] < stack[top]) { // 如果比栈顶元素小,则入栈;
if (top + 2 > stack.size()) {
stack.push_back(0);
}
top++;
stack[top] = nums2[i];
}
}
while (top != -1) { // 判断栈目前是否为空,不为空还要构造剩下元素和-1的映射
m[stack[top]] = -1;
top--;
}
for (int k = 0; k < nums1.size(); k++) {
ans.push_back(m[nums1[k]]);
}
return ans;
}