hulu往届笔试题及解题思路

第一题

题目描述:

给定一个正整数组a,返回一个新的数组sums,满足sums[i]的值为正整数组a中比a[i]小的数字之和;如果不存在比a[i]小的数字,则sums[i]为0。已知数组a中元素最大值不超过100000,数组长度不超过10000,数组元素允许重复。

输入:

第一行为整数n,表示数组的长度。接下来的n行数字表示数组里的元素。

输出:

正整数数组sums,使得sums长度与a长度相同。

输入样例:

45429

输出样例:

62011

第二题

题目描述:

给定一个圆,圆心在原点。给定圆上的一组点a[i](i = 1, 2, …, n),各点互不重复,且用x轴正方向逆时针转至与该点所在半径重合时所转角度的100倍(整数)表示,取值范围是[0, 36000)。我们可以从这组点中任选三点组成一个三角形。请问最多可以组成多少个钝角三角形?

输入:

第一行为一个正整数, n为点的个数。n <= 1000。接下来n行,每一行有一个整数,每个数表示在圆边上的一个点。

输出:

任选三点时,可以组成的钝角三角形的数量。

输入样例甲:

40100001200018000

输出样例甲:

2

输入样例乙:

4900002700018000

输出样例乙:

0



第三题

题目描述:

建造房子是一项复杂的工程。施工队的设计师小张将造房子分成了m个任务,任务标号为1到m,每个工人一天能完成一个任务,任务之间可能有依赖。施工队里有n个工人,每一天,工人们依次从当前没有依赖的任务中选择标号最小的任务去做。问房子需要多少天建成?

输入:

第一行为三个整数:m,n,k。其中:m为任务个数,n为工人个数。 1 <= mn <= 21474836470 <= k <= 2147483647接下来有k行,每一行有两个数字:i,j。表示标号为i的任务依赖于标号为j的任务。其中:1 <= ij <= m且 (i,j) 的组合不会重复出现

输出:

如果房子能建成,输出一个整数,表示需要花多少天。如果房子不能建成,输出E。

输入样例甲:

6 2 52 13 15 25 36 5

输出样例甲:

4

输入样例乙:

7 2 63 12 15 46 47 64 7

输出样例乙:

E

第四题

题目描述:

要砌一面合适的墙有严格的要求: 
1. 墙上不得有任何空隙; 
2. 为了保证墙足够结实,墙绝对不能被垂直地切分成两面墙(反例如下图所示); 
3. 所有的砖块只能水平地放置,即长边必须同水平面平行;   
小明是一名砌墙工人,现在小明拥有四种尺寸的砖块,分别是1x1, 1x2, 1x3, 1x4,如果他需要砌一面尺寸为NxM(N表示高度,M表示宽度)的墙,并需要满足以上三个要求,请问一共可以有多少方案?

输入:

第一行为输入的数据组数T。接下来有T行,每一行有两个数字:N和M,N表示高度,M表示宽度。

输出:

输出为T行结果,表示成功的砌墙方案数。

输入样例:

42 23 22 34 4

输出样例:

3793375

Hulu往届校招编程测试解析

第一题

真题解析:

解法一:暴力求解。即两层遍历,内层遍历找出数组中比当前数字小的数字并求和。时间复杂度为O(n^2)。
解法二:由解法一,内层遍历的复杂度是O(n),根据题意是求比某元素小的元素之和,可以联想到对数组进行排序,那么“求原数组中小于某元素数字之和”的问题就转化为了“计算排序后数组中该元素所在位置前面的数字之和”的问题。并且可以观察到,对于排序后的数组b及小于b[i]的元素之和sum[i],有sum[i] = b[i-1] + sum[i-1],可知可以通过复用前面的计算结果进而提升性能。此题另外需要注意的是,要考虑数组中有重复的情况。优化后的算法时间复杂度为O(nlgn),空间复杂度为O(n)。

第二题

真题解析:

这道题最根本的问题是,给定三个点后,如何判断组成的是钝角三角形。
最直观的方式是,在半个圆的角度之内的任意三点组成的三角形都是钝角三角形。所以暴力解法的话可以对所有点循环一遍,检测是否是钝角三角形,时间复杂度为O(n^3)。
既然组成钝角三角形的三个点一定在180度内,那么也可以先行排序。根据点的顺时针方向去对每个点寻找自己作为顺时针起点时,180度内有多少个钝角三角形。假设顺时针180度内还有n个点,则该点作为顺时针起点的钝角三角形数量为C(n, 2)。在排序后一遍O(n)即可算出来,总的时间复杂度为O(nlogn)。

第三题

真题解析:

这道题目的场景十分常见,题目可以描述为实现一个可以调度相互依赖的、可并行执行的任务的系统。为了简化题目描述和实现,出题人加了两个约束:

1. 每个任务的执行时间一样;

2. 每一天总是从最小的任务开始挑选。
实现的方法比较直观,就是维护一个可执行任务的集合,每个循环开始的时候从最小的任务开始执行,再把新出现的没有依赖的任务加进去。
需要注意的地方有几点:
1. 某一天执行完所有任务后,再把新的任务加进去,不要每执行完一个就添加;
2. 这个可执行任务的集合最好用堆或者优先队列,这样不用每一天都排序;
3. 需要理解房子不能建成,是因为有循环依赖。

第四题

真题解析:

首先以输入N=3、M=2为例,每层可以有一个1*2或由两个1*1的砖拼成,那么总共可能的拼墙方案有2^3=8种,其中,不合法的拼墙方案是每层都由两个1*1的砖拼成,所以答案是8-1=7种。

对于其他的输入,可以用类似的思路,先求出所有的可能方案,然后减去所有不合法的方案,就是最终的答案。
为求所有的可能方案,需求出每层都多少种拼墙方案,这是个简单的dp,row[i]表示用四种长度的砖拼成长度为i的一层有多少种方案,递推方程是row[i] = row[i-1] + row[i-2] + row[i-3] + row[i-4]。总的解决方案就是any[i] = row[M]^N。
为求所有不合法的方案,需要遍历墙会在哪个地方(i)第一次可以被切分,被切分的左边是所有合法的墙,右边是所有可能的墙,所以转换成另一个dp。solid[i]表示一面i*N的墙有多少种合法方案,递推方程是solid[i] = sum(solid[j]*any[i-j])),j在1到i之间。solid[M]就是最终的解。
除此之外,还需要考虑大数据的问题,在计算的过程中都需要注意取模,注意好细节就可以了。

原文地址:https://www.cnblogs.com/vector11248/p/11432345.html