问题:给定一个数组,求每个元素右边第一个比它大的数
目录
739. 每日温度
【题目】:
【方法1】:暴力法,遍历
效果:
复杂度O(),因为进行了很多不必要的比较。如数组[5,4,3,2,1,6],当计算5时需要从4遍历到6,当计算4时需要从3遍历到6,显然3,2,1遍历多次是多余的。我们发现计算当前元素5时只需与4右边第一个比4大的数6比较,同样,计算4时只需与3右边第一个比3大的数6比较,这样每个数只遍历一遍,效率就更高了。
那么用什么方法实现呢,这里我们引入单调栈的概念,维护一个递减栈,栈顶元素最小。
单调栈更多分析可参考:https://blog.csdn.net/pengchengliu/article/details/93461922
- 如果当前元素 T(cur) 大于栈顶元素,计算栈顶元素的结果,栈顶元素弹出,继续用当前元素与下一个栈顶比较,直到栈为空或当前元素 T(cur) 小于栈顶元素。
- 如果栈为空或当前元素 T(cur) 小于栈顶元素,则当前元素进栈。
- 为方便计算索引差,栈中存储的是元素的索引。
【方法2】:递减栈
效果:
改进:用数组实现栈
- 进栈:stack[++top]
- 出栈:stack[top--]
- 查看栈顶元素:stack[top]
- 栈为空:top=-1
效果:
【方法3】:另一种单调栈见https://blog.csdn.net/pengchengliu/article/details/93461922的【方法1】
【方法4】:递推(动规包括递推和记忆化搜索)
从最后一天倒推着推。最后一天温度显然不会再升高,结果直接为0。倒数第二天的温度如果比倒数第一天低,那么结果为1;如果比倒数第一天高,则温度不会再升高,所以倒数第二天的结果也应该为0。
由此可知,要求出第 i 天对应的结果,只需要查询第 i+1 天对应的结果就可以:
若T[i] < T[i+1],那么res[i]=1;
若T[i] > T[i+1],那么查询res[i+1]:
- 如果 res[i+1] = 0,即第 i 天温度比第 i+1 天高,并且第 i+1 天之后的天气不会有升高,则res[i]=0;
- 如果 res[i+1] != 0,即第 i 天温度比第 i+1 天高,并且第 i+1 天之后的天气会有升高,则令 j=i+1,比较T[i]和T[j+res[j]],即将“第i天的温度”与“比第i+1天大的那天的温度”进行比较。
效果:
单调栈和递推方法需要重点掌握。
503. 下一个更大元素 II
【题目】:
【代码】:
【方法1】:栈,同739题的方法2
效果:
改进:用数组实现栈,同739题
效果:
496. 下一个更大元素 I
【题目】:
【方法1】:先把nums2中数和索引存到map,nums1中的数 x 根据map找到其在nums2中的索引 index,用暴力法找到nums2中第一个比x大的数。
效果:
【方法2】:不同与方法1的是,方法2先把nums2中数 x 和 x 右边第一个比 x 大的数存到hashMap,即 map.put(x, x 右边第一个比 x 大的数),遍历nums1,在hashMap中去查找“下一个更大元素”,当找不到时则为-1。
效果: