我是个菜鸟
时隔这么长时间,我终于是将接雨水做出来了,呜呜呜
想了解曲折历程的可以看这两篇
废话不多说,直接看思路,这个题最重要的思想就是动态规划,至于如何很好的利用动态规划,我还没有很好的理解,等再历练几题后再对动态规划进行总结。 好的,先把题目引过来
这个接雨水啊,我想过从头看,想过从尾看,也想过从中间向两端看。这些显然是比较蠢的。
最终解题思想
动态规划的思想,就是动态的对结果进行修改,所以我们就从头看,一个一个的看。那每个位置的雨水量怎么看呢?我们都了解木桶效应吧,需要找最短板!!!在这我们不能直接拿每个位置的两端进行比较,因为,你看到的不一定是对的。因为每个位置可能顶上有水,所以我们需要动态的改变每个位置的高度。
所以我们就把开始位置后的最高位置当成是木桶的另一边,这里就用一个冒泡排序找
high = start + 2;
for (int i =start + 2;i < height.length;i++){//冒泡排序找到后面最大元素及其位置
if (height[i] > height[high])
high =i;
}
从start + 2位置开始找,因为至少有一个间隔才能有雨水。
这里我选择start记录当前到达的位置,然后记录start + 1位置存储的雨水,这里要有一个判断,当start + 1位置高度小于两侧才能存储雨水
if(height[start + 1] < Math.min(height[start], height[high])){
result += Math.min(height[start], height[high]) - height[start + 1];
height[start + 1] = Math.min(height[start], height[high]);
}
然后对start进行自增,再进行这个过程,直到start到倒数第三个位置,这是最后一个可能有雨水的地方,用一个while循环即可。完整代码如下
class Solution {
public int trap(int[] height) {
int start = 0;
int high = 0;
int result = 0;
while(start <= height.length - 3){
if(start == high){
high = start + 2;
for (int i =start + 2;i < height.length;i++){//冒泡排序找到后面最大元素及其位置
if (height[i] > height[high])
high =i;
}
}
if(height[start + 1] < Math.min(height[start], height[high])){
result += Math.min(height[start], height[high]) - height[start + 1];
height[start + 1] = Math.min(height[start], height[high]);
}
start++;
}
return result;
}
}
这个题的解法灵感来自于它的孪生兄弟
这个题的思想也是动态规划,如果是和我一样的算法小白可以先去做这个,做不出来看看答案,然后当你对动态规划有一定了解后可以尝试做接雨水,这个一定要多尝试,不要做几次就看答案。
这个题我是做了很长时间的,中间也是故意放开了一段时间,想着之后回来也许就有不同思想了,虽然有点笨,但这个是我独立做出来的还是很高兴的。
最后是我的一些感想
通过接触了一些动态规划的题目,我认为这类题暴力求解是无法解出的,时间复杂度太大了。再给你一个巨长巨长的数据,直接就宕了,所以我们思考问题不要太过死板。我现在这个解法其实也是比较慢的,有更好解法的小伙伴们欢迎来分享。