每日箴言:
一支笔,一包烟,一个hard坐一天 ......
1、题目
今天整一道困难水平的题目 !!!
2、分析
⑴ 、初始化左指针 left 和右指针 right 分别指向数组的两端
⑵ 、初始化左边最大值 leftMax 和右边最大值 rightMax,初始值为数组左端元素和右端元素的高度
⑶ 、初始化雨水容量 water 为 0
⑷ 、当 left <= right 时,执行以下步骤:
如果 height[left] <= height[right],表示左边高度较小,则比较 height[left] 和 leftMax 的大小:
如果 height[left] < leftMax,说明左边可以接住雨水,雨水高度为 leftMax - height[left],
将其累加到 water 中
更新 leftMax 为 left 位置的高度
向右移动左指针,即 left++
如果 height[left] > height[right],表示右边高度较小,则比较 height[right] 和 rightMax 的大小:
如果 height[right] < rightMax,说明右边可以接住雨水,雨水高度为 rightMax - height[right],将其累加到 water 中
更新 rightMax 为 right 位置的高度
向左移动右指针,即 right--
如果 height[left] == height[right],表示左右高度相等,可以选择任意一边移动。在这里选择向左移动右指针,即 right--
⑸ 、返回计算得到的雨水容量 water
3、解题
/**
* 接雨水
* <p>
* 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
* <p>
* 首先,要形成凹槽才能接到雨水,凹槽的特征就是中间小,两边大 ,这是一个特点
* 其次,观察图发现,凹槽形成还有一个特征,就是数组会经历一个先递减,再递增的过程,递增到最高处再递减,如果反复形成凹槽
* 这是一个分析的点,这道题你可以横着来做,也可以竖着来做
*
* 下面是一种解法
*
*
* @param height
* @return
*/
public static int trap(int[] height) {
int left = 0;
int right = height.length - 1;
int leftMax = 0;
int rightMax = 0;
int water = 0;
while (left <= right) {
if (height[left] <= height[right]) {
if (height[left] < leftMax) {
water += leftMax - height[left];
}
leftMax = Math.max(leftMax, height[left]);
left++;
} else {
if (height[right] < rightMax) {
water += rightMax - height[right];
}
rightMax = Math.max(rightMax, height[right]);
right--;
}
}
return water;
}