今天的每日一题,因为给的用例只有一个,再加上自己考虑问题不够全面,提交了四次才成功。。。没提交一次发现一点设计缺陷,然后改了再错,。。。自己还是太菜了
解题思路
直方图的蓄水能力取决于当前的最低点的高度以及当前最低点和最高点的距离。借鉴"双指针"和单调栈的思想,使用两个栈分别辅助进行顺序和倒序的计算,最后将两部分的结果相加就可以了。
对输入案例[0,1,0,2,1,0,1,3,2,1,2,1],以顺序为例。
- 栈为空,所以0入栈。“指针”指向1;
- 因为1比当前的栈顶元素0大,所以1入栈,“指针”指向0;
- 因为0比当前的栈顶元素1小,所以执行medium = medium + s.peek() - height[i],“指针”指向2;就像前面提到的,蓄水的量取决于当前栈顶元素,所以通过前面的公式可以消除内部“石块”对结果的影响;
- 因为2比当前的栈顶元素1大,所以2入栈,result += medium,medium重置为0,并记录当前栈顶元素的索引值index,“指针”指向1;
- 如此重复,直至对整个数组完成遍历,此时栈顶元素为3,index为7,result为5;
下面开始反向遍历,因为只需要找到最大的值后停止,所以j的索引值最小为上面的index
过程和顺序遍历的一样,最后得到结果1
两部分的结果加起来得到最终结果6
代码
class Solution {
public int trap(int[] height) {
int length = height.length;
int medium = 0;
int result = 0;
Stack<Integer> s = new Stack();
Stack<Integer> s1 = new Stack();
int index=0;
for(int i = 0; i<length;i++)
{
if(s.empty())
{
s.push(height[i]);
}
else
{
if(s.peek() <= height[i])
{
s.push(height[i]);
index = i;
result += medium;
//System.out.println(result);
medium = 0;
}
else{
medium = medium + s.peek() - height[i];
// System.out.println(medium);
}
}
}
if (index == length-1)
return result;
//System.out.println("res"+result);
medium = 0;
for(int j = length-1; j>=index;j--)
{
if(s1.empty())
{
s1.push(height[j]);
}
else
{
if(s1.peek() <= height[j])
{
s1.push(height[j]);
result += medium;
medium = 0;
}
else{
medium = medium + s1.peek() - height[j];
}
}
}
return result;
}
}