题意:
解题思路:
思路:1. 双指针扫描 O(n) 1.1 找到图中最高的矩形,然后从左至右扫描到最高点,从右到左扫描到最高点; 1.2 从左至右扫描到最高点,如果右边矩形高度小于左边矩形高度,计算差值; 1.3 从右到左扫描到最高点,如果左边矩形高度右边右边矩形高度,计算差值; 1.4 最后统计总差值2. (单调栈) O(n) 1.1 如果要求水的面积,一定要形成一个U字形 1.2 维护一个递减的单调栈,如果下一个i大于栈顶元素,我们pop出栈顶的元素(即凹槽的部分),再判断是否栈顶元素是否为空,如果不为空,则一定可以形成一个U字形 1.3 计算U形面经:($i - $stack->top() - 1) * (min($height[$i], $height[$stack->top()]) - $height[$top]); 1.4 min($height[$i], $height[$stack->top()] : 木桶原理,蓄水的面经由最短的那块板子决定 1.5 (min($height[$i], $height[$stack->top()]) - $height[$top]):如果$height[$top]有值,必须去掉这部分值,不然面积多算了这部分值;
PHP代码实现:
class Solution { function trap($height) { $area = 0; $maxIdx = $this->getHeight($height); $leftHeight = $height[0]; for ($i = 0; $i < $maxIdx; $i++) { //下一个小的话就计算面积 if ($leftHeight < $height[$i]) { $leftHeight = $height[$i]; } else { $area += $leftHeight - $height[$i]; } } $rightHeight = $height[count($height) - 1]; for ($i = count($height) - 1; $i > $maxIdx; $i--) { if ($rightHeight < $height[$i]) { $rightHeight = $height[$i]; } else { $area += $rightHeight - $height[$i]; } } return $area; } function getHeight($height) { $maxV = 0; $maxIdx = 0; for ($i = 0; $i < count($height); $i++) { if ($height[$i] > $maxV) { $maxV = $height[$i]; $maxIdx = $i; } } return $maxIdx; } function trapByStack($height) { $stack = new SplStack; $res = 0; for ($i = 0; $i < count($height); $i++) { if ($stack->isEmpty() || $height[$i] < $height[$stack->top()]) { $stack->push($i); } else { while (!$stack->isEmpty() && $height[$i] > $height[$stack->top()]) { $top = $stack->pop(); if (!$stack->isEmpty()) { $res += ($i - $stack->top() - 1) * (min($height[$i], $height[$stack->top()]) - $height[$top]); } } $stack->push($i); } } return $res; }}
GO代码实现:
func trap(height []int) int { if len(height) == 0 { return 0 } left, right, res, leftMax, rightMax := 0, len(height)-1, 0, 0, 0 for left < right { if height[left] <= height[right]{ // 左->右 if height[left] >= leftMax { leftMax = height[left] } else { res += leftMax - height[left] } left++ } else { // 右->左 if height[right] >= rightMax { rightMax = height[right] } else { res += rightMax - height[right] } right-- } } return res}