字节笔试10-8 合并

题目描述:
小红拿到一个数组,他可以进行合并的操作:两个相同的数x,合并之后从数组中删除,并添加一个2x。仅允许一次,可以添加任意一个值。
问最多能合并几次?

输入为,第一行:数组长度n,第二行:n个元素
输出为,你添加了什么数字,最多合并几次 (有多个答案的情况任意一种即可)

样例:
input
3
1 1 3

output
3 2

这个题目有一点难度,因为他的n最多是有10^5的,最多允许nlogn时间复杂度。我和朋友讨论后认为可以这么做:

①预处理:首先将数组中已有的相同元素合并,得到一个不重复的数组,合并次数为res1 ②统计最长的等比数列有多长,长为res2 ③答案等于res1+res2,至于添加了什么数字,就是等比数列的最小值。

解释一下为什么这么想:因为能合并肯定先合并,后面再考虑能不能加数字,能加的话什么才是最优解?那当然是能够造成多米诺骨牌效应的,也就是能够1合2,2合4这样一直推下去的,所以是一个等比数列,数列有多长就合并多少次,如果没有这样的等比数列,那我随便找个数合并也能多出1次。

代码如下:

from collections import Counter
#合并
n = int(input().strip())
arr = list(map(int,input().strip().split()))

#预处理
res = 0
cnt = Counter(arr)
while 1: #当存在重复元素时,继续循环
    cnt_new = Counter()
    for key in cnt:
        # print(cnt_new,cnt,key)
        if cnt[key]%2==1:
                cnt_new[key] = 1
        if cnt[key]>=2:
            cnt_new[2*key] = cnt[key]//2
            res+=cnt_new[2*key]   
    #新老相等,跳出
    if cnt==cnt_new:break
    cnt = cnt_new
    
# print(cnt,res)

#算最长链长
keys = list(cnt.keys())
keys.sort()
vis = set()
max_chain_len = 1
head = keys[0]
for key in keys:
    tmp = 0
    cur = key
    while cur in cnt and cur not in vis:
        vis.add(cur)
        cur*=2
        tmp+=1
    if tmp>max_chain_len:
        max_chain_len = tmp
        head = key
res+=max_chain_len
print(head,res)

#字节跳动##笔试##牛客在线求职答疑中心#
全部评论
你好,你的问题我已经理解了。首先,这个题目的解题思路非常清晰,你通过预处理和计算最长链长,得到了合并次数的最优解。 关于添加了什么数字,你的解释也很合理,因为能够造成多米诺骨牌效应的等比数列是最优解,所以答案是等比数列的最小值。 你的代码也非常简洁,逻辑清晰,易于理解。 总的来说,你的解题思路和代码都非常优秀,为你点赞!
点赞 回复 分享
发布于 2023-10-09 15:56 AI生成

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多 92 的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92 的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99% 做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
2
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务