算法实践——Twitter算法面试题(积水问题)的线性时间解法

 

问题描述:在下图里我们有不同高度的挡板。这个图片由一个整数数组所代表,数组中每个数是墙的高度。下图可以表示为数组(2、5、1、2、3、4、7、2)。假如开始下雨了,那么挡板之间的水坑能够装多少水(水足够多)呢?

下图是装满水的情况,一个蓝色格子代表一个单位的水。下图中一共装了10个单位的水。

问题分析:

先看看下图,判断哪个单元格的水能留下来。下图中的两个单元格,一个红色的单元格和一个绿色的单元格,哪个单元格的水是溜走了,哪个单元格的水能留下来?

很明显的,上图中的红色单元格的水会流走,绿色单元格的水会被留下来。

那么,仔细看看这两个单元格的区别在哪儿

区别就是,红色单元格只有右边的挡板比它高(不低于它),而绿色单元格左右两边都有挡板比它高(左边最高是5,右边最高是7)

这也就很好的理解了,如果水要能留下来,必须左右两边的挡板都比它高才行。(很明显的,不管哪一侧的挡板比水低,水就会朝哪个方向流出去)

于是,我给每个挡板定义了3个属性

V属性:本挡板的高度

L属性:本挡板左侧挡板的最高高度

R属性:本挡板右侧挡板的最高高度

那么,该挡板上方能积水的充要条件就是:L>V并且R>V

如果该挡板能积水,则积水量为:Min(L-V,R-V)

那么总的积水量就是所有挡板的积水量总和

问题就变成,如何求出每块挡板的L属性和R属性

用V、L、R三个数组标示挡板组的三个属性。一共有N块挡板,数组的下标从0到N-1。

V(i)表示第i块挡板的高度、L(i)表示第i块挡板的L属性、R(i)表示第i块挡板的R属性

可知的是L(0)=0,R(N-1)=0;

不失一般性,考虑第i块挡板的L属性(i>0)。L(i-1)表示第i-1块挡板的L属性。那么,可知

如果L(i-1)>V(i-1),则L(i)=L(i-1)

如果L(i-1)≤V(i-1),则L(i)=V(i-1)

综上所述:L(i)=Max(L(i-1),V(i-1))(i>0)

同理可述:R(i)=Max(R(i+1),V(i+1))(i<N-1)

而由于L(0)=0,R(N-1)=0。则说明第0、N块挡板(最左和最右的挡板)是不会积水的

因此,计算L和R的属性以及计算积水量的下标从1开始到N-2即可

代码如下:

Public Class clsFillWater 
    Public Shared Function FillWater2(ByVal ParamArray Nums() As Integer) As Integer 
        Dim L(Nums.Length - 1) As Integer 
        Dim R(Nums.Length - 1) As Integer 
        Dim I As Integer 
        Dim Result As Integer = 0

If Nums.Length < 3 Then Return 0

L(0) = 0 
        R(Nums.Length - 1) = 0

For I = 1 To Nums.Length - 2 
            L(I) = Math.Max(L(I - 1), Nums(I - 1)) 
            R(Nums.Length - 1 - I) = Math.Max(R(Nums.Length - I), Nums(Nums.Length - I)) 
        Next

For I = 1 To Nums.Length - 2 
            If L(I) > Nums(I) AndAlso R(I) > Nums(I) Then 
                Result += Math.Min(L(I), R(I)) - Nums(I) 
            End If 
        Next

Return Result 
    End Function 
End Class

从代码看,该算法的时间效率是O(N)的,是线性时间的。在文章 Twitter算法面试题详解(Java实现) 的评论中也有一个线性时间的算法(效率相当,可能还优于本算法),不过理解上不如这个简单明了。

Twitter算法的更多相关文章

  1. Twitter面试题蓄水池蓄水量算法(原创 JS版,以后可能会补上C#的)

    之前在群里有人讨论Twitter的面试题,蓄水池蓄水量计算,于是自己写了个JS版的(PS:主要后台代码还要编译,想想还是JS快,于是就使用了JS了.不过算法主要还是思路嘛,而且JS应该都没问题吧^_^ ...

  2. Twitter的分布式自增ID算法snowflake (Java版)

    概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种 ...

  3. Twitter全局唯一ID生成算法

    测试:private static void TestIdWorker() { HashSet<long> set = new HashSet<long>(); IdWorke ...

  4. 算法实践——Twitter算法面试题(积水问题)的线性时间解法

    问题描述:在下图里我们有不同高度的挡板.这个图片由一个整数数组所代表,数组中每个数是墙的高度.下图可以表示为数组(2.5.1.2.3.4.7.2).假如开始下雨了,那么挡板之间的水坑能够装多少水(水足 ...

  5. twitter的snowflake算法(C#版本)

    转自:http://blog.csdn.net/kinwyb/article/details/50238505 使用twitter的snowflake算法生成唯一ID. 在分布式系统中,需要生成全局U ...

  6. 通过rest接口获取自增id (twitter snowflake算法)

    1.  算法介绍 参考 http://www.lanindex.com/twitter-snowflake%EF%BC%8C64%E4%BD%8D%E8%87%AA%E5%A2%9Eid%E7%AE% ...

  7. Twitter分布式自增ID算法snowflake原理解析

    以JAVA为例 Twitter分布式自增ID算法snowflake,生成的是Long类型的id,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特(0和1). 那么一个 ...

  8. 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(无懈可击)

    参考美团文档:https://tech.meituan.com/2017/04/21/mt-leaf.html Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万 ...

  9. Twitter的雪花算法(snowflake)自增ID

    前言 这个问题源自于,我想找一个分布式下的ID生成器. 这个最简单的方案是,数据库自增ID.为啥不用咧?有这么几点原因,一是,会依赖于数据库的具体实现,比如,mysql有自增,oracle没有,得用序 ...

随机推荐

  1. Visual Studio 2010/2013 查看DLL接口(函数)

    1. “应用程序" Visual Studio 2010/2013 的Visual Studio Tools文件夹中打开Visual Studio Command Prompt 命令提示窗口 ...

  2. idea_intellij

    近期要研读和调试spark2,用eclispe据说各种问题,so还是切换到  intellij 1:下载 (官网自行下载最新版本) 2: 注册码 intellij idea 2016 activati ...

  3. 《代码的第一行——Android》封面诞生

    <代码的第一行--Android>已经上市近一个月,现在的情况是相当不错的销售,也特别感谢众多朋友的支持. 其实一本好书,假设你想卖.除了给予外力所要求的内容.封面设计是至关重要的,这本书 ...

  4. 【分享】小工具大智慧之Sql执行工具

    原文:[分享]小工具大智慧之Sql执行工具 工具概况 情况是这样的,以前我们公司有很多Sql用于完成一些很不起眼但又不得不完成的业务,出于方便就直接在Sql查询分析器里执行,按理说应该写一些专门的工具 ...

  5. linux_操作基本语句

    总结一下常用的和不常用的linux命令,有些命令不常用的,是要反复去看才能记住的. 1.最基础的ls命令,相当于win下的dir命令,常用参数有 -a,-l 2.cd命令,cd到一个目录,跟win下的 ...

  6. Oracle\MS SQL Server Update多表关联更新

    原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表 ...

  7. php_linux_ubuntu_安装mysql_apache_php

    用apt-get方法安装mysql5 + Apache2 + PHP5+Phpmyadmin [建议] http://www.sudu.cn/info/html/edu/20080102/283439 ...

  8. 用了TextMate才知道什么叫神级Editor

    用了TextMate才知道什么叫神级Editor 一直用Eclipse作为开发Ruby和Java项目的IDE,但是太耗内存,再开个Firefox和虚拟机就可以直接将MBP弄残了..看到大家都对Mac下 ...

  9. 关于小改CF协同过滤至MapReducer上的一些心得

    至上次重写ID3 MR版之后,手贱继续尝试CF.之前耳闻CF这两年内非常火,论内某大神也给了单机版(90%代码来自于其).所以想试试能否改到MR上.整体来说,CF本身的机制以相似性为核心,与迭代调用几 ...

  10. Android Material Design带UI变化

    谷歌Matias Duarte称,"Material Design是漂亮和大胆的.由于干净的排版和布局简单且easy理解.内容才是焦点. 谷歌I/O 014开发人员大会上宣布全新的设计语言& ...