Trapping Rain Water 题解
题目描述
即现实中的地面积水问题。抽象出来即从某个序列Seq
中提取出先单调递减后单调递增的子序列集合(集合中子序列只允许头尾存在重复),求此集合中所有子序列s
(长为d
)的"凹陷值"((d - 2) * min{s[0],s[d-1]} - (sum(s) - s[0] - s[d-1])
)之和。
如:[0,1,0,2,1,0,1,3,2,1,2,1]
,积水量为6
。
题解
即抽象成以上描述中的数学问题。那么遍历寻找单调递增单调递减序列即可。寻找过程中记录下序列的起始位置,结束位置,即可进行子序列s
的"凹陷值"计算。因为是从头到尾遍历序列,所以时间复杂度为O(n)
。而这过程只需要常数个变量就可以完成,所以空间复杂度为O(1)
。
例如[0,1,0,2,1,0,1,3,2,1,2,1]
。子序列集合为{[1,0,2], [2,1,0,1,3], [3,2,1,2]}
,相应的"凹陷值"为[1,4,1]
,总和为6
。
代码
class Solution {
public:
int trap(vector<int>& height) {
int len = height.size();
if (len < 3)
return 0;
int sum = 0, range = 0, preIndex = 0;
for (int i = 1; i < len; ++i) {
if (height[i] >= height[preIndex]) {
sum += height[preIndex] * (i - preIndex - 1) - range;
preIndex = i;
range = 0;
} else {
range += height[i];
}
}
int end = preIndex;
range = 0; preIndex = len - 1;
for (int i = len - 2; i >= end; --i) {
if (height[i] >= height[preIndex]) {
sum += height[preIndex] * (preIndex - i - 1) - range;
preIndex = i;
range = 0;
} else {
range += height[i];
}
}
return sum;
}
};
总结
主要应用了数学抽象思想。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。