【Jobs】阿里算法实习生笔试——墙之间积水体积

题目描述

初步分析

情况1:未遇到全局最大值之前

该情况只需要保存现在的截止目前的临时最大值tempMax,然后积水体积是tempMax-height[i]。

情况2:已经遍历过了全局最大值,后面的数值虽然有局部极值,但没有再出现全局最大值

情况3:已经遇到全局最大值,但是遇到了第二个极值比之前遇到的第一个极值要大,那么积水的体积就是全局最大值和第二次的遇到的极值(即次大值)之间的容积了

总结情况2和情况3,在第三次遇到的极值要和次大值比较。

情况4:其实这里和情况1是一样的

为什么这里会列出来这个呢?

因为题目要求只能遍历一次数组,我们不确定在一次遍历的过程中是不是还能碰到全局最大值,所以,这里考虑局部极值和全局最大值的关系就显得尤为重要。

相比情况2和情况3,在第三次遇到的极值要和最大值比较。

我们要在一次遍历的过程中判断局部极值点,然后比较局部极值点和暂时的最大值和次大值的大小关系,根据不同的情况来做出相应的动作。

反其道而行之

上面的分析看似把情况都考虑到了,但这使得问题扩散开来。尤其是当阶段性的极值不是最大值也不是次大值的情况就无法解决。所以,我们应该反其道而行之,换个角度来简化问题。

我们一直在考虑当遇到最大值之后,如何进行比较来计算后续的蓄水容积的情况,但这样不如从最后设定一个下标来反向计算。于是这就形成了解决这个问题的核心思路:分别从头尾设置两个下标i,j,首先比较这两个下标对应的值的大小,由对应值小的那个下标先移动,并记录该下标的当前的临时最大值(比如i先移动,记录i_max),当遇到一个新的最大值的时候,不但要对i进行局部变量的清零,还要比较该最大值与j所对应值的大小关系,然后较小值对应的下标继续移动,直到两个下标相遇,遍历了一遍数组为止。

程序代码

int Volume(int* height, int n)
{
    int i = 0;
    int j = n-1;
    int i_max = height[i];
    int j_max = height[j];
    int volume = 0;
    const int i_walk = 1;
    const int j_walk = 2;
    //i_max <= j_max , i先走
    int who_walk = i_max <= j_max ? i_walk : j_walk;

    while(i != j)
    {
        if(who_walk == i_walk)
        {
            if(i_max > height[i])
            {
                volume += i_max-height[i];
            }
            else
            {
                i_max = height[i];
                if (i_max > j_max)
                {
                    who_walk = j_walk;
                    continue;
                }
            }
            ++i;
        }
        else if(who_walk == j_walk)
        {
            if(j_max > height[j])
            {
                volume += j_max-height[j];
            }
            else
            {
                j_max = height[j];
                if (j_max >= i_max)
                {
                    who_walk = i_walk;
                    continue;
                }
            }
            --j;
        }
    }
    return volume;
}

转载请注明作者Jason Ding及其出处

GitCafe博客主页(http://jasonding1354.gitcafe.io/)

Github博客主页(http://jasonding1354.github.io/)

CSDN博客(http://blog.csdn.net/jasonding1354)

简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)

百度搜索jasonding1354进入我的博客主页

时间: 2024-08-07 07:08:52

【Jobs】阿里算法实习生笔试——墙之间积水体积的相关文章

2014腾讯实习生笔试——蒙特卡洛算法求圆周率

这是2014腾讯实习生笔试(西安,武汉站)的第26题.给出二个函数,让你去理解其含义.答案是:第一个函数式用来产生(a,b)之间的随机小数.第二个函数式用蒙特卡洛概率算法求近似圆周率. 先介绍一下该方法(蒙特卡洛算法): 以 概率和统计理论方法为基础的一种计算方法.将所求解的问题同一定的概率模型相联系,用计算机实现统计模拟或抽样,以获得问题的近似解.比方,给定 x=a ,和 x=b ,你要求某一曲线 f 和这两竖线,及 x 轴围成的面积,你能够起定 y 轴一横线 y=c 当中 c>=f(a) a

阿里客户端在线笔试

2015.4.2 刚刚进行了阿里的在线笔试,虽然是客户端的岗位,但是前面的题好像都没有和“我以为和客户端相关”的题,各种“当时我就懵逼了”.果然是阿里. 这样子也知道了自己的差距,我觉得考PAT靠谱多了,求今年六月份能去考PAT,fighting.(只能这样安慰自己了) 选择题: 1.<国王和天使>的游戏,每个人把自己的名字写在纸条上并且丢入盒子中,等所有人完成后,每个人再从盒子里抽一张小纸条,上面的人物就是自己的国王,自己就是ta的天使. 如果抽到自己就重抽,直到抽到别人为止.然后大家为小纸

面试算法实习生

昨天刚开始是笔试,完事后两面技术面,最后hr面.第一次面试算法实习生,在此做下笔记,记录面试问题与自己的不足. 笔试: 回来看牛客网,居然发现大部分都有,但可惜我还没刷. 回忆下知识点从网上搜出这套题好多都有(2,5,6,7,8,9,21,42,46,48,49,53,55) 一.选择题 1. 某超市研究销售纪录数据后发现,买啤酒的人很大概率也会购买尿布,这种属于数据挖掘的哪类问题?(A) A. 关联规则发现 B. 聚类 C. 分类 D. 自然语言处理 2. 以下两种描述分别对应哪两种对分类算法

软考类----来自淘米2004实习生笔试

淘米2014实习生笔试,今年是淘米第一年招暑期实习生,笔试好大部分考的是软考的题目啊啊啊啊(劳资后悔当年没考软考刷加权),其他是浅而泛的风格,C++,SQL语句,数据结构(哈夫曼树,二叉查找树,栈后缀表达式,连通无向图),排序算法各种最优最差平均 复杂度-- 下面记一下考到的软考风格的题目,不过估计其他家也不会考(劳资什么时候能过个笔试额,锁定C++不搞JS了) 1.计算机中最适合进行数字加减运算的编码是_补码__,最适合表示浮点数的数字编码是_移码__. A.原码 B.反码 C.补码 D.移码

算法实现柱形集合积水面积

用一个数组代表柱形墙的的高度.当下雨的时候柱形墙能积水的体积是多少 下面是python的实现算法: # -*- coding: utf-8 -*- def savewater(arr): point_l=0 max_l=arr[0] point_r=len(arr)-1 max_r=arr[len(arr)-1] volume=0 #point_l从左向右遍历,point_r从右向左遍历 while point_l<point_r: #能积水的标准时两边的高度大于中间的 if max_l<ma

DP - tencent2016实习生笔试A

tencent2016实习生笔试A Problem's Link ---------------------------------------------------------------------------- Mean: 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢?输出需要删除的字符个数. analyse: 对于这题来说,插入字符和删除字符使其成为回文串,答案是一样的. 首先求s的反串rs,然后对s和rs求最长公共子序列,要删除的字

笔试真题 ALBB-2015 算法工程师实习生 笔试真题 解析

1.用十进制计算30!(30的阶乘),将结果转换成3进制进行表示的话,该进制下的结果末尾会有____个0. [解析] 计算N!下3进制结果末尾有多少个0,其实就是计算3进制中的3被进位多少次,只要将N!因式分解成3^m*other,m就是答案.技巧性的解法就是m=N/3+N/(3^2)+N/(3^3)....+N(3^k) (k<=N/3) -- N=30:N/3+N/9+N/27=14. 2.小赵和小钱二人分别从寝室和图书馆同时出发,相向而行.过了一段时间后二人在中途相遇,小赵继续向图书馆前进

阿里题目总结:——阿里巴巴2015实习生笔试真题

(1)编译和体系结构: 2 以下指令集架构属于复杂指令集架构的是? 正确答案: D   你的答案: D (正确) ARM MIPS SPARC 以上皆不是 解析: 常用的精简指令集: RISC 微处理器包括 DECAlpha . ARC . ARM . AVR . MIPS . PA-RISC . PowerArchitecture(包括 PowerPC) 和 SPARC 等. 复杂指令: CISC如X86 (2)十进制与二进制间的转换: 十进制整数转换为二进制整数采用"除2取余,逆序排列&qu

拼多多 2019 春季算法实习生在线笔试

1. 题目一 给出两个数组,求两个数组对应元素乘积的最小值. 先对两个数组排序,然后用第一个数组的最大值和第二个数组的最小值相乘,依次遍历即可. ?#include <iostream> #include <stdio.h> #include <vector> #include <algorithm> using namespace std; bool ascend(int i, int j) {return (i < j);} bool descen