算法(一)

  

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;
        }    

 

 

 

 

 

 

//

 

posted on 2015-09-22 20:10  alex_cool  阅读(237)  评论(0编辑  收藏  举报