台阶积水算法探讨

关于台阶积水算法思路的梳理。

问题

有一组不同高度的台阶,有一个整数数组表示,数组中每个数是台阶的高度,当开始下雨了(雨水足够多)台阶之间的水坑会积水多少呢?
如下图,可以表示为数组[0,1,0,2,1,0,1,3,2,1,2,1],返回积水量6。

思路梳理

考虑积水量,可以分析每一级台阶会有多少积水。
首先开头和结尾的台阶不会有积水。中间部分的台阶存在积水,那么它的两端肯定有比它要高的台阶。
基于这个思路,设计了算法1;

private static void getwater(int[] orgin){int size=orgin.length;System.out.println(Arrays.toString(orgin));int[] water= new int[size];//每一级台阶积水量int left=orgin[0];//左边最高台阶int right=0;water[0]=0;for(int i=1;i<size;i++){if(orgin[i]>=left){//如果是目前为止最高台阶,则更新最高台阶高度,同时改台阶积水为0;left=orgin[i];water[i]=0;}else{right=orgin[i];for(int j=i;j<size;j++){//找出右边最高台阶if(orgin[j]>right){right=orgin[j];}}if(right>orgin[i]) {右边最高台阶高于当前台阶,当前台阶积水,否则积水为0;int result = left > right ? right : left;water[i]=result-orgin[i];}else{water[i]=0;}}}System.out.println(Arrays.toString(water));}

通过对算法1的求解过程进行反推,发现有大量的重复工作在查询右边最高台阶上,基于性能的考虑,对算法1进行修改得到算法2:

private static void getwater2(int[] orgin){int size=orgin.length;System.out.println(Arrays.toString(orgin));int[] water= new int[size];int maxNum=0;for(int i=0;i<size;i++){//第一次遍历得到最高台阶高度if(orgin[i]>maxNum){maxNum=orgin[i];}}for(int i=0;i<size;i++){//初始化积水统计数组water[i]=maxNum-orgin[i];}int left=orgin[0];if(water[0]>0){//不是开头最高water[0]=0;for(int j=1;j<size&&orgin[j]<maxNum;j++){if(orgin[j]>=left){left=orgin[j];water[j]=0;}else{water[j]=left-orgin[j];}}}int right=orgin[size-1];if(right>0){//不是结尾最高water[size-1]=0;for(int j=(size-2);j<size&&orgin[j]<maxNum;j--){if(orgin[j]>=right){right=orgin[j];water[j]=0;}else{water[j]=right-orgin[j];}}}System.out.println(Arrays.toString(water));}

每一级台阶积水最多是最高一级台阶高度减去当前台阶高度。用这个值初始化积水数组可用避免最高级台阶数不止一个时的遗漏。然后分别从左端和右端求每一级台阶的积水量,最终只会遍历数组两次,时间复杂度为O(n),而算法1 的时间复杂度是O(n2).

台阶积水问题算法思考相关推荐

  1. 分布式唯一id:snowflake算法思考

    匠心零度 转载请注明原创出处,谢谢! 缘起 为什么会突然谈到分布式唯一id呢?原因是最近在准备使用RocketMQ,看看官网介绍: 一句话,消息可能会重复,所以消费端需要做幂等.为什么消息会重复后续R ...

  2. 基于双向匹配的陌生人社交策略及算法思考

    前言 作为连接人的工具,社交产品的价值不言而喻:熟人社交领域,微信已占据绝对霸主地位,但是在陌生人社交领域还未出现类似绝对地位的产品,今天就以探探和Tinder为例,跟大家聊聊陌生人社交.本文主要通过 ...

  3. 台阶问题---动态规划算法

    问题描述 所谓的台阶问题就是说,从0开始上台阶1,2,3...n,每次只能上1个或者2个台阶.问上到n个台阶有多少种走法.这个问题是比较典型的,也有很多种变形,我们先讲解下这种的实现. 问题分析 我们 ...

  4. ElGamal 算法思考

    前驱知识: 离散对数问题 离散对数 百度百科介绍: 在整数中,离散对数(英语:Discrete logarithm)是一种基于同余运算和原根的一种对数运算.而在实数中对数的定义 logba是指对于给定 ...

  5. 基于行为心理学的网络购物推荐算法思考

    移植自己的一篇博客,以作备份.https://my.oschina.net/u/1395815/blog/909194 背景: 随着互联网的发展,网络购物系统在整个购物体系中所占比例越来越大,淘宝.京 ...

  6. “生命游戏”的多线程算法思考[转]

    Intel正在ISN网站上举办一个多线程编程大赛,值得关注.Intel过去几年举办过好几次线程技术大赛,包括与topcoder合作的一些竞赛,质量都不错.题目难度适中,而且具有启发性,对多核编程感兴趣 ...

  7. “生命游戏”的多线程算法思考

    Intel正在ISN网站上举办一个多线程编程大赛,值得关注.Intel过去几年举办过好几次线程技术大赛,包括与topcoder合作的一些竞赛,质量都不错.题目难度适中,而且具有启发性,对多核编程感兴趣 ...

  8. 多路宽带聚合(绑定)的算法思考

    最近涉及到网络多路(>=2路)宽带的应用,起初觉得已经9102年了,多路应用应该处于很成熟的状态,然而实际来看不论是硬件还是软件,都远没有预期的成熟. 在日常应用中,通常会遇到随着单路宽带容量提 ...

  9. 音频识别算法思考与阶段性小结

    这篇文章酝酿了很久,一直没抽时间写. 在中秋,国庆来临之时,落笔. 写之前,先交代几件事情, 主要是 回复 给我发邮件以及QQ上询问的朋友们的一些疑问和需求,这里稍作回复一下. 1.关于 票据ocr预 ...

最新文章

  1. 程序员过关斩将--面试官再问你Http请求过程,怼回去!
  2. php方案报价单,综合布线设计方案,综合布线报价清单
  3. linux下yum包更新不了
  4. Python可视化 | Matplotlib绘制圆环图的两种方法!
  5. 洛谷 - P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并(树上差分+线段树合并)
  6. ie8一下解决圆角,阴影不兼容问题
  7. java 重定向 https_使用简单身份验证从HTTP重定向到HTTPS
  8. 2022年最值得学习的 5 种编程语言,你有在学习吗?
  9. springboot设置运行内存_Docker 如何运行多个 Springboot?
  10. d3.js 旋转图形_MATLAB 的图形处理
  11. java判断是否手机浏览器_User-Agent判断是什么浏览器
  12. 1.6数组-像素翻转
  13. python基础篇--从零开始(下)
  14. WEB前端使用SheetJS读写excel文件
  15. 【c语言课程设计】C语言校园卡管理系统
  16. 解决虚拟机桥接模式无法上网的问题
  17. Counting Stars HDU - 6184
  18. GDB attach 调试
  19. premiere如何把多个视频放在同一个视频画面
  20. 摄像头V4L2编程应用开发

热门文章

  1. win10设置虚拟内存_Win10安装后必做的优化,解决电脑卡顿问题,实用收藏系列...
  2. 智慧养老之居家养老解决方案
  3. PHP openssl_encrypt openssl_decrypt 尝试
  4. 四月英语总结—开始读书加油
  5. AD19原理图绘制_学习笔记
  6. Ubuntu安装anaconda做英文词云
  7. Spanable和span使用
  8. 长链接转短链接的一次尝试
  9. Android测量图像中物体大小,android – 如何使用OpenCV从图像中检测(计数)头发?
  10. Android亮屏、熄屏控制