我在一张试卷上看了这个问题,在答案本上找到了一个答案。我不明白它背后的算法。谁能给我解释一下这个算法是如何工作的?
给定n个非负整数,表示每个条形宽度为1的高程图,计算下雨后它能够捕获多少水。
例如,给定输入
[0,1,0,2,1,0,1,3,2,1,2,1]
字符串
返回值为
6
型
答案是这样的
public class Solution {
public int trap(int[] height) {
if (height.length <=2 )
return 0;
int h = 0, sum = 0, i = 0, j = height.length - 1;
while(i < j)
{
if ( height[i] < height[j] )
{
h = Math.max(h,height[i]);
sum += h - height[i];
i++;
}
else
{
h = Math.max(h,height[j]);
sum += h - height[j];
j--;
}
}
return sum;
}
}
型
谢谢
9条答案
按热度按时间xxe27gdn1#
时间复杂度为O(1),空间复杂度为O(N)。
逻辑:
->让我们从0 index循环到输入值的末尾。
->如果我们发现一堵墙大于或等于前一堵墙
->在名为prev_index的变量中记录该墙的索引
->保持将前一个墙的高度减去当前(第i个)墙添加到可变水。
->有一个临时变量,它也存储与水相同的值。
->循环到最后,如果你没有发现任何墙大于或等于前一个墙,然后退出。
->如果上面的点为真(即,如果prev_index < size of input array),则从water中减去temp变量,并从输入数组的末尾循环到prev_index,并找到大于或等于前一个墙的墙(在本例中,从后面开始的最后一个墙)
这里的概念是,如果右边有一个较大的墙,你可以保留水的高度等于左边较小的墙。
如果右边没有更大的墙,那就从左边开始。现在左边肯定有更大的墙了。你实际上循环了两次,所以O(2N),但渐近O(N),当然还有O(1)空间。
Java代码:
字符串
w9apscun2#
字符串
代码:
型
e5njpo683#
字符串
jaql4c8m4#
字符串
fruv7luv5#
WoDoSc很好地画了一张海拔和被困水的图表。水只能被困在两个更高的海拔之间。
我所做的是运行代码并输出结果,这样你就可以看到被困的水是如何计算的。代码从“山”的两端开始。
如果两端的高度相同,则右端会移近中心。您可以将左端移近中心。
第一列是左侧立面的高度和索引。第二列是右侧立面的高度和索引。
第三列是最大最小高度。换句话说,左边或右边的最大高度,以较小的最大值为准。这个数字对确定当地水位很重要。
第四列是总和。
跟着图沿着,你就能看到算法是如何工作的。
字符串
下面是代码。将print和println语句放在适当的位置可以帮助你理解代码在做什么。
型
lmvvr0a86#
我知道这可能不是最好的方式来表示它的图形,但你可以想象的情况下图:
的数据
其中红色条是地形(根据您的示例数组的高程),蓝色条是可以被“困”到地形的“山谷”中的水。
为了简化,该算法从左到右循环所有条形图(如果left较小)或从右到左(如果right较小),变量
h
存储在循环的每一步期间找到的最大高度,因为水不能高于地形的最大高度,并且要知道可以捕获多少水,它将水的高度(最大高度h
)与特定点的地形高程之间的差值求和,以获得实际水量。yqkkidmi7#
该算法的工作原理是从左边(i)和右边(j)处理陆地。i和j是计数器,它们朝着彼此靠近陆地的中间。
h是一个变量,它跟踪迄今为止考虑到下侧而发现的最大高度。
土地是通过让i和j“相向”工作来处理的。当我读代码时,我想象了两堵假想的墙,把水挤向中间,最低的墙向较高的墙移动。算法继续计算水的体积。它使用h - height[x]因为水只能在两个墙之间的最低点的内部被容纳。所以本质上它继续从左边和右边加总水的体积并减去水被更高海拔的地块取代。
也许更好的变量名应该是
2exbekwf8#
我认为上面的解决方案很难理解。我有一个简单的解决方案,需要O(n)额外的空间和O(n)时间复杂度。
算法步骤
1.维护一个数组,该数组包含当前元素右侧所有元素的最大值.
2.从左侧保持变量max,其包含当前元素左侧的所有元素的最大值。
3.查找数组中已经存在的max from left和max from right的最小值。
4.如果最小值大于数组中的当前值,则添加数组中的差值,并添加与当前值的差值,并从左侧更新max。
字符串
可能我的算法和上面的一样,但是我认为这个实现很容易理解。
k5ifujac9#
在Java中解决了收集雨水的问题。
字符串