Leetcode-496-下一个更大元素 I

问题描述:

思路:

这道题题目都读了半天才明白,翻译的实在有点...

暴力:遍历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;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值