1.有一组表示墙的数组a[],其中a[i]表示第i个墙的高度,如下图,
假如下雨了,求墙里可以装多少水
如果我们从左至右遍历列表,每个下标水的量最多是到现在为止最大的数。这表示如果我们已知右边有相等或更大的,我们可以知道存下的水有多少。反向遍历的时候也一样:如果我们知道左边有比右边最大的数更大的,我们装水是毫无问题的。
基于这个想法,一个解决方法是:先找到最大值,从左遍历到最大值,然后从右遍历到最大值。这个方法需要两次遍历:一次找到最大值,另一次分成了两个子遍历。
优化:
假设区间的右边界比左边界高,则存水高度就是由左边界确定的,此时将左边界向右移动,途中就可以直接计算在该墙之上的存水量是多少。若在移动过程中遇到了比左边界高的墙,说明之前移动扫过的是一个单独的水坑。然后从右往左移动,直到全部扫描一遍。
static int GetWater(int[] walls) { int left = 0; int right = walls.Length - 1; int maxLeft = walls[left]; int maxRight = walls[right]; int volume = 0; while (right > left) { if (maxLeft < maxRight) {//从左向右遍历 left++; if (walls[left] > maxLeft) maxLeft = walls[left]; else volume += maxLeft - walls[left]; } else {//从右向左遍历 right--; if (walls[right] > maxRight) maxRight = walls[right]; else volume += maxRight - walls[right]; } } return volume; }
//