Google Foobar问题‘Please Pass the Coded Messages’代码报错求助
Google Foobar挑战:"Please Pass the Coded Messages"代码问题排查
问题背景
偶然碰到Google Foobar的这个题目,提交代码后5个测试用例中有1个失败,反复检查找不到问题。
题目描述
需要向兔子工人传递消息,需用印有0-9的盘子组合成能被3整除的数字作为代码。给定包含若干数字(0-9)的列表L,编写函数solution(L),用部分或全部数字组成能被3整除的最大数,无法组成则返回0。列表L长度为1-9,数字可重复但每个元素仅能使用一次。
示例
输入:
solution.solution([3, 1, 4, 1])输出:
4311输入:
solution.solution([3, 1, 4, 1, 5, 9])输出:
94311
我的代码
def jointer(l): res=0 for i, v in enumerate(l): if v==0: res=res*10 else: res+=v*10**i return res def solution(L): L=sorted(L) ll=[] s=0 for i in L: ll.append(i%3) s+=i r=s%3 if r==1: if 1 in ll: L.pop(ll.index(1)) else: for _ in range(2): L.pop(ll.index(2)) elif r==2: if 2 in ll: L.pop(ll.index(2)) else: for _ in range(2): L.pop(ll.index(1)) return jointer(L)
代码问题分析
你的代码存在两个核心问题:
1. 依赖静态的ll列表导致索引越界
ll列表是基于初始排序后的L生成的,当你删除L中的元素后,ll并不会同步更新。如果第二次删除时,ll.index(目标值)返回的是初始列表中的索引,而这个索引已经超出了当前L的长度,就会触发IndexError。
比如测试用例[2,3,5]:
- 排序后
L = [2,3,5],ll = [2,0,2],总和10模3余1 - 需要删除两个模3为2的元素,第一次删除
L[0](对应ll[0]),此时L = [3,5] - 第二次调用
ll.index(2)返回初始索引2,但当前L长度仅为2,执行L.pop(2)会直接报错。
2. 未处理删除元素数量不足的情况
当需要删除两个元素(比如余1但没有模1元素,需要删两个模2元素),但L中模2元素不足2个时,代码仍会强行执行两次pop,同样会引发索引越界错误,最终导致测试用例失败。
修正思路
每次删除元素时,基于当前的L重新计算需要删除的目标元素,而不是依赖初始的ll列表:
def jointer(l): res = 0 for i, v in enumerate(l): if v == 0: res = res * 10 else: res += v * 10 ** i return res def solution(L): L = sorted(L) total = sum(L) remainder = total % 3 if remainder == 1: # 找所有模3为1的元素,删除最小的 ones = [x for x in L if x % 3 == 1] if ones: L.remove(ones[0]) else: # 找所有模3为2的元素,需要至少2个才能删除 twos = [x for x in L if x % 3 == 2] if len(twos) >= 2: L.remove(twos[0]) L.remove(twos[1]) else: return 0 elif remainder == 2: # 找所有模3为2的元素,删除最小的 twos = [x for x in L if x % 3 == 2] if twos: L.remove(twos[0]) else: # 找所有模3为1的元素,需要至少2个才能删除 ones = [x for x in L if x % 3 == 1] if len(ones) >= 2: L.remove(ones[0]) L.remove(ones[1]) else: return 0 return jointer(L) if L else 0
内容的提问来源于stack exchange,提问作者rapping_overFlow
相关产品推荐
相关产品推荐

