单调栈--每日温度

题目
根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/daily-temperatures
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

  1. 理解题目以后,直接想到的思路就是 逐个遍历,然后对每个元素 向后遍历寻找比他大的元素,下标差 则是解,代码见1笨方法。
  2. 这种每个都去遍历的场景,很容易出现重复计算,由于是向右边找,如果想利用前面的计算成果,当然是从右边开始遍历啦。当右边的res数组已经计算完毕以后,如果你对i这个下标进行查找,
    (1)发现 i+1符合要求,而i+1已经计算过了,则可以直接跨res[i+1] 个下标,继续匹配大小。就节省了重复的遍历,提高效率。
    (2)如果你发现i+1不符合要求,并且 res[i+1]是0 ,请立马结束遍历,res[i] 必须是0(这个也是重点)。
    代码见2.笨方法的优化
  3. 也可以使用栈来实现这个功能,如果你存储元素的值的话,当出栈以后。你不知道他下标是啥,就无法 对res赋值。所以更机智的办法就是直接在栈里存储下标,反正有数组。下标就能代表整个元素,完美! 由于是要 寻找比他大的元素,so,
    (1)当遍历到的元素,比栈顶元素 大的时候,妥妥的出栈,然后求个下标差就好了嘛。不过这是其中一种场景
    (2)如果遍历到的元素比栈顶小,就要先入栈,猥琐发育,别浪,(当然栈里面元素目前是单调递减哦)当遇到比栈顶大的以后,栈顶出栈!计算下标差,放入res数组。然后新栈顶来到pk台上,若遍历到的元素继续卫冕冠军,新栈顶出栈!直到栈内 没有元素了 或者 栈里元素更大,那卫冕冠军的下标就入栈咯。所以 for循环里面对栈的操作要是个while循环,(当栈内有元素并且栈顶元素比 目前遍历的元素小,要一直不停的比较,出栈)结束以后,当前遍历的元素下标入栈就好了嘛。结束!

1.笨方法

public int[] getRes(int [] T) {
	int length = T.length;
	int[] res = new int[length];
	for(int i = 0;i < length;i++) {
		for(int j = i+1; j < length;j++) {
			if (T[j] > T[i]) {
				res[i] = j-i;
				break;
			}
		}
	}
	return res;
}

2.笨办法的优化

public int[] getRes(int [] T) {
	int length = T.length;
	int[] res = new int[length];
	for(int i = length-2;i >= 0;i--) {
		for(int j = i+1; j < length;j+=res[j) {
			if (T[j] > T[i]) {
				res[i] = j-i;
				break;
			} else if(res[j] == 0){
				res[i] == 0;
				break
			}
		}
	}
	return res;
}

3.单调栈 (知识点)

public int[] getRes(int [] T) {
	int length = T.length;
	int[] res = new int[length];
	Stack<Integer> stack = new Stack();
	for(int i =0;i < length;i++) {
		while(!stack.isEmpty() && stack.peek() < T[i]) {
			int peek = stack.peek();
			res[peek] = i-peek; 
			stack.pop();
		}
		stack.push(T[i]);
	}
	return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值