算法(一)

摘要:
反向遍历也是如此:如果我们知道左边的数字比右边的数字大,那么我们加载水就没有问题。该方法需要两个遍历:一个是查找最大值,另一个是分为两个子遍历。如果在移动过程中遇到高于左侧边界的墙,则表明前一次移动扫过了单独的集水坑。然后从右向左移动,直到完成所有扫描。

  

1.有一组表示墙的数组a[],其中a[i]表示第i个墙的高度,如下图,

假如下雨了,求墙里可以装多少水

算法(一)第1张

如果我们从左至右遍历列表,每个下标水的量最多是到现在为止最大的数。这表示如果我们已知右边有相等或更大的,我们可以知道存下的水有多少。反向遍历的时候也一样:如果我们知道左边有比右边最大的数更大的,我们装水是毫无问题的。

基于这个想法,一个解决方法是:先找到最大值,从左遍历到最大值,然后从右遍历到最大值。这个方法需要两次遍历:一次找到最大值,另一次分成了两个子遍历。

优化:

假设区间的右边界比左边界高,则存水高度就是由左边界确定的,此时将左边界向右移动,途中就可以直接计算在该墙之上的存水量是多少。若在移动过程中遇到了比左边界高的墙,说明之前移动扫过的是一个单独的水坑。然后从右往左移动,直到全部扫描一遍。

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

//

免责声明:文章转载自《算法(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇修改 tomcat 内存MFC学习(1)——CFileDialog()用法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java 的ArrayList构造方法

目录 ArrayList 构造方法使用 ArrayList 类常用方法 ArrayList集合存储字符串遍历 简单的学生管理系统   1、ArrayList 构造方法 ArrayList类概述  什么是集合   提供一种存储空间可变的存储模型,存储的数据容量可以发生改变 ‘   ArrayList集合的特点 底层是数组实现的,长度可以变化   泛型的...

hash表的理解

哈希表 先从数组说起 任何一个程序员,基本上对数组都不会陌生,这个最常用的数据结构,说到它的优点,最明显的就是两点: 简单易用,数组的简易操作甚至让大多数程序员依赖上了它,在资源富足的情况下,我们甚至会无意识地忽略其它更适用的数据结构而使用数组(别说你没这么干过..)。 查找的快速性,数组中查找元素可以直接通过下标进行定位,速度快。 我在刚开始写程序...

js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素

 壹 ❀ 引 在JS开发工作中,遍历数组的操作可谓十分常见了,那么像for循环,forEach此类方法自然也不会陌生,我个人也觉得forEach不值得写一篇博客记录,直到我遇到了一个有趣的问题,我们来看一段代码: let arr = [1, 2]; arr.forEach((item, index) => { arr.splice(inde...

C# TreeView 建立、遍历树(递归)

刚接触treeview这个功能,恶补了几天,博主总结下实现的功能以备用,希望能帮到需要的亲~~ C#gui程序中建立树状结构、遍历树状结构、树状结构节点选中联动(选中父节点时,自动选中其全部子节点,取消选中的某子节点,取消其相应的所有父节点的选中),读取选中节点信息。 0.最初的父节点建立ParentNode = tv_user.Nodes.Add(OUn...

Spark聚合操作:combineByKey()

Spark中对键值对RDD(pairRDD)基于键的聚合函数中,都是通过combineByKey()实现的。 它可以让用户返回与输入数据类型不同的返回值(可以自己配置返回的参数,返回的类型) 首先理解:combineByKey是一个聚合函数,实际使用场景比如,对2个同学的3门考试科目成绩,分别求出他们的平均值。 (也就是对3门考试成绩进行聚合,用一个平均数...

idea中的后缀补全

IDEA有个很牛逼的功能,那就是后缀补全(Postfix Completion),这个功能可以通过后缀来使用代码补全进行模板式地补全语句,如遍历循环语句(for、foreach)、使用 String.format() 包裹一个字符串、使用类型转化包裹一个表达式、根据判(非)空或者其它判别语句生成 if 语句、用instanceOf生成分支判断语句等。 听起...