阿里7.24笔试题解

楼主没有参加这场笔试,在牛客网上看到题目,做了一些整理。


1. 吃烧饼。有n个盘子,每个盘子内有w[i]个烧饼。每次选取一个1≤x≤n,可以吃到1-x号盘子里的一个烧饼。若这x个盘子中有空盘时无法进行该操作。

问经过任意多次这种操作后,最多可以吃掉多少烧饼。


分析:不难得知,对每个盘子,最多可吃的数量为:它和它前面的盘子中最少的烧饼数。

用一个变量cur记录到目前盘子为止最少的烧饼数即可。时间复杂度O(n)

def p1(arr):
    cur, ret = arr[0], 0
    for v in arr:
        cur = min(cur, v)
        ret += cur
    return ret


2. 开关灯。N行L列的灯,有L个开关,第i个开关Li可以控制第i列,打开该开关使得该列灯状态反转。

行之间可以任意交换,问给定初始灯状态s和目标灯状态t,能否从初始变到目标状态,如果能,最少要打开几个开关。


分析:s的第1行s1一定对应t的某一行tk。如果已知k,通过对比s1tk各列的灯状态可以得知每一个开关Li是否需要打开。

由于行之间可以任意交换,我们只需要验证在按照上面确定的开关状态下,两组灯状态的集合{s1,...,sN}和{t1,...,tN}是否相等。



我们用一个二进制数表示每一行灯的开关状态,如0010表示第三列灯开,其他灯关。验证集合相等可以在Python中用Counter类(哈希表)来实现。

时间复杂度:我们需要对k=1,...,N做搜索。每次搜索需要判断集合是否相等,这可以在O(NL)的时间内完成;总体复杂度O(N2L)。



from collections import Counter

def p2(s, t, L):
    ret = L + 1
    set_s = Counter(s)
    
    for t_k in t:
        flip = s[0] ^ t_k
        nflip = bin(flip).count('1')
        if nflip < ret and set_s == Counter(t_i ^ flip for t_i in t):
            ret = nflip
    
    return ret if ret <= L else -1





#阿里巴巴##笔试题目#
全部评论
楼主,请教个很简单的问题,第一题为什么“对每个盘子,最多可吃的数量为:它和它前面的盘子中最少的烧饼数。”?没看明白这题为什么这么做?
点赞 回复 分享
发布于 2020-07-25 22:21
老哥强
点赞 回复 分享
发布于 2020-07-26 12:13
第一题有点问题,如果是3 1 2,第一次x=3,吃三个变成2 0 1,后面还可以令x=1两次,变成0 0 1,感觉应该有递归。
点赞 回复 分享
发布于 2020-07-27 16:30
不太懂 就求问,第二题为什么只对s[0]求翻转次数呢?
点赞 回复 分享
发布于 2020-07-28 23:59
请问大佬,我怎么感觉第二题的复杂度应该是O(N^3L)?因为固定了第一行的,那剩下的每一行就要比较其他行,复杂度就是O(N^2)吧,那每一次比较复杂度就是O(L),那一次比较总复杂度就是O(N^3L),第一行和其他的行匹配情况也要考虑的话就是O(N^3L)了吧
点赞 回复 分享
发布于 2020-07-30 10:40

相关推荐

不愿透露姓名的神秘牛友
昨天 11:05
点赞 评论 收藏
分享
0offer底层废物双飞牛马:这找不到我就只有原地去世了
点赞 评论 收藏
分享
11-08 10:39
门头沟学院 C++
点赞 评论 收藏
分享
11 29 评论
分享
牛客网
牛客企业服务