ps:即使通过题目,也要去看下优质题解,对比下别人的代码实现, 有时能从代码中发现一些新的思路和未考虑完全的细节!!!
思路:将一整个区域分成若干个小区域看,高低起伏
1.记录每个板子上的雨水数量,最后相加求和。h=板高
2.-->由于每个板子区间能装多少水取决于他的最大前缀板高和最大后缀板高,
3. 然后根据短板效应,则每个板子区间最多装-->min(前缀max,后缀max) min-h;
4.由双指针双向移动,前指针所指向的板子的最大前缀值都已记录了,所以只需注意最大后缀即可,同理,后指针指向的板子也如此,
5.特点是:本质上是比较前后缀的max,移动较小的那个,因为已经较小的那个根据条件已经可以计算出装水量,可以进入下一个板子.(较难点:思路应该按规则从首尾逐渐向内部考虑,不能从局部直接去推测各种极端情景,因为由于规则的限定,这种极端情景压根不存在。)
6.在「谁小移动谁」的规则下,两个指针中必有一个指针已经指向了当前最大的一个板子。(ps:板子即柱子)
主要问题:1. 前后缀max相等的话则移动哪个指针?移动一个还是两个?
2.先移动哪个指针?
3.注意 while
循环可以不加等号,因为在「谁小移动谁」的规则下,相遇的位置一定是最高的柱子,这个柱子是无法接水的。
解答问题:
修正:1.当二者相等时,根据6规则,此时两边都是当前最高的柱子,并且它们的接水量由共同前后缀决定,所以接水量均为0,此时任意移动其中一个指针即可(初始化首尾一样,无影响)。
2.双指针初始化在首尾位置,通过5规则后再移动即可,不需考虑此问题。
总结:
1.大拆小,由中间局部推整体区域。
2.每个板子区间能装多少水取决于他的最大前缀板高和最大后缀板高->本质是比较出最大前后缀谁是短板,再根据3计算。
易错点:
1.当有两个移动指针时,容易惯性思维造成细节错误,比如i++,j++,但实际双向移动是j--
2.前后指针相等的情况容易判断失误,实际相等时只需移动其中一个指针,
当只有三个板子的时候,同时移动两个,会提前结束循环条件,那么中间的水会漏算。