トピック:
所与nはずっと雨雨を取ることができ、次いで1列の幅の高さマップ算出さクリックコラム装置の非負整数を表します。
上記配列[0,1,0,2,1,0,1,3,2,1,2,1]図高度に表される、この場合には、6つのユニットを取ることができ、雨水(青部分)が雨を表します。
例:
入力:[0,1,0,2,1,0,1,3,2,1,2,1]出力:6
考えました:
スクラッチサイクル、検出された各<高さ[i]が、残りはこの領域のサイズ数(見つかりません、二番目に高いポイントが算出される)=、中間高さを除去される(I〜次)、及びI =継続して次の
2(水に類似して埋め)を考えます:
ダブルポインタの法則は:常にローエンドの影響によって呼び出された水は、それが高いパーティ運動に向けたポインタは、高いストップに行くたびに下げることができるので、下、それぞれにポインタを移動します現在のブロックの統計水頭症量
コード:
#if 0
//思路一:从头开始循环,每次找到<=height[i]的数(没找到,则使用次高点计算),去掉中间的高度,剩下的就是这块区域(i~next)的大小,然后i=next继续
class Solution {
public:
int trap(vector<int>& height) {
int i = 0, j = 0, second_h = 0;
int next;
int ret = 0;
int len = height.size(); //不能直接用height.size()-2因为当长度为0时,这个值不为-2
while(i < len-2)
{
if(height[i] == 0)
{
i++;
continue;
}
second_h = i+1;
//不能用函数lower_bound,因为无序
next = my_next(height, i+1, height.size(), height[i], second_h);
cout<<i<<" "<<next<<" "<<second_h<<endl;
if(next == height.size()) //说明没有比这个高的了,则用次高位计算
{
ret += (second_h - i-1)*height[second_h];
for(j = i + 1; j < second_h; j++)
ret -= height[j];
i = second_h;
}
else
{
ret += (next - i-1)*height[i];
for(j = i + 1; j < next; j++)
ret -= height[j];
i = next;
}
}
return ret;
}
private:
int my_next(vector<int>& height, int begin, int end, int target, int& second_h){
for(int i = begin; i < end; i++)
{
if(height[second_h] <= height[i])
second_h = i;
if(height[i] >= target)
return i;
}
return end; //表明未找到
}
};
#endif
#if 1
//双指针法:因为积水总是受到叫低的一端影响,所以可以每次将较低的指针朝着较高的一方移动,会到更高的就停止,将较低的指针移动,每次统计当前块的积水量
class Solution {
public:
int trap(vector<int>& height) {
if(height.size() < 3)
return 0;
int temp1 = 0, temp2 = 0, i=0, j = height.size()-1, count = 0;
while(i < j)
{
if(height[i] < height[j])
{
if(temp1 < height[i])
temp1 = height[i];
else
count += temp1 - height[i];
i++;
}
else
{
if(temp2 < height[j])
temp2 = height[j];
else
count += temp2 - height[j];
j--;
}
}
return count;
}
};
#endif