Google Foobar挑战Power Hungry:隐藏测试用例3失败求排查
排查Google Foobar Power Hungry挑战的代码问题
看起来你的代码在几个关键场景和效率上存在问题,这应该就是隐藏测试用例没通过的原因。咱们一步步拆解问题,再给出正确的解法:
你的代码存在的核心问题
1. 错误的乘积截断逻辑
你代码里的if mul > 1000: break完全是多余且错误的。题目并没有限制乘积的大小,相反,最大乘积可能是一个极大的数(比如多个大正数相乘),这个break会提前终止乘积计算,导致你得到错误的中间值,直接影响最终结果的正确性。
2. 枚举所有子集的效率瓶颈
用itertools.combinations生成所有非空子集的时间复杂度是O(2^n),当输入列表的长度n较大时(比如n=30以上),这种方法会因为超时无法通过测试用例——Foobar的隐藏用例大概率包含这类大规模输入。
3. 负数、零的场景处理缺失
你的代码没有针对性处理这些特殊情况:
- 偶数个负数相乘的结果是正数,可能比单个正数的乘积更大;
- 奇数个负数时,应该去掉绝对值最小的那个负数(即最大的负数),让剩余负数的乘积为正数;
- 如果所有元素都是负数,最大乘积应该是其中最大的那个负数(绝对值最小的);
- 当所有非零元素的乘积为负数时,零可能成为更优的选择(比如输入
[-3, -2, 0],最大乘积是0)。
正确的解法思路
我们不需要枚举所有子集,而是通过数学逻辑直接计算最大乘积:
- 将输入列表分为正数、负数、零三个部分;
- 处理负数部分:如果负数个数是奇数,移除其中绝对值最小的负数(也就是最大的负数);
- 计算所有剩余正数和处理后负数的乘积;
- 最后根据乘积的情况判断结果:如果乘积为空(比如所有元素都是负数且个数为奇数,移除后无元素),则返回零(如果有零)或最大的那个负数;否则返回计算出的乘积。
修正后的代码
def answer(xs): # 处理特殊情况:只有一个元素时直接返回 if len(xs) == 1: return str(xs[0]) positives = [] negatives = [] has_zero = False # 分类遍历输入元素 for num in xs: if num > 0: positives.append(num) elif num < 0: negatives.append(num) else: has_zero = True # 处理奇数个负数的情况:移除最大的负数(绝对值最小) if len(negatives) % 2 != 0: negatives.remove(max(negatives)) # 计算总乘积 product = 1 for p in positives: product *= p for n in negatives: product *= n # 判断最终结果 if product == 1: # 说明没有正数,且处理后也没有负数,返回零(如果存在) return "0" if has_zero else str(max(xs)) else: return str(product)
关键逻辑说明
- 单个元素的特殊处理:避免后续逻辑出错,直接返回该元素的字符串形式;
- 分类处理:把正、负、零分开,便于针对性计算;
- 负数处理:确保负数的乘积是最大的可能正数;
- 结果判断:当乘积为1时,意味着没有可相乘的正负数,此时优先返回零(如果有),否则返回原列表中最大的元素(全负数场景)。
内容的提问来源于stack exchange,提问作者Shaikh Naushad
相关产品推荐
相关产品推荐

