/**
* 最简单莫过于双重循环,笔试时至少不会丢分
* 时间复杂度:O(n^2)
* 空间复杂度:O(n)
*/
//外层循环是一次遍历给定数组, 内层循环是不断的寻找比外层循环此时遍历到的元素大的数,
//并用res持续的记录下最大的index差值
public int[] dailyTemperatures(int[] T) {
int[] res = new int[T.length];
for (int i = 0; i < T.length - 1; i++) {
for (int j = i + 1; j < T.length; j++) {
if (T[j] > T[i]) {
res[i] = j - i;
break;
}
}
}
return res;
}
通常是
一维数组, 要寻找一个元素的右边或者左边第一个比自己大或者小的元素的位置, 此时我们就可以想到用单调栈
。
那么单调栈的原理是什么呢?为什么时间复杂度是O(n)就可以找到每一个元素的右边第一个比它大的元素位置呢?
单调栈的本质是
空间换时间, 因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素, 优点是只需要遍历一次。
- 单调栈里存放的元素是什么?
单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
- 单调栈里元素是递增还是递减的?
从栈顶到栈底的顺序
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
//维护递减栈,后入栈的元素总比栈顶元素小。
//比对当前元素与栈顶元素的大小
//若当前元素 < 栈顶元素:入栈
/若当前元素 > 栈顶元素:弹出栈顶元素,记录两者下标差值即为所求天数
//这里用栈记录的是 T 的下标。
Deque<Integer> stack = new LinkedList<>();
int len = temperatures.length;
int[] res = new int[len];
int index = 0;
for(int i = 0; i < len; i++){
int temperature = temperatures[i];
//当前元素 > 栈顶index的元素
//弹出preIndex, 记录preIndex与当前元素i的index差值, 更新到res[preIndex]
while(!stack.isEmpty() && temperature > temperatures[stack.peek()]){
int preIndex = stack.pop();
System.out.println("i为: " + preIndex);
//System.out.println("preIndex为: " + preIndex);
res[preIndex] = i - preIndex;
System.out.println(Arrays.toString(res));
}
//当前元素 <= 栈顶index的元素
//入栈当前元素
stack.push(i);
}
return res;
}
}