Python递归实现零钱兑换时报TypeError: 'NoneType' object is not iterable如何解决
报错原因排查与修复
1 直接报错的核心原因
list.remove()是原地修改方法,执行后返回值为None,你的代码中递归调用时直接把coins.remove(max(coins))的返回值作为新的coins参数传入下一层,下一层递归拿到的coins就是None,后续执行max(coins)、all(coins)时试图迭代None对象,就抛出了TypeError: 'NoneType' object is not iterable错误。
修复方式:先移除最大值,再传入修改后的coins数组:
max_val = max(coins) coins.remove(max_val) return coinChange(coins, amount, final_list)
2 其他需要修正的逻辑问题
all(coins) > amount判断完全错误:all()函数作用是判断列表所有元素是否为真值(非0、非空),返回布尔值,布尔值和整数比较时True等价于1、False等价于0,完全达不到你要判断「所有硬币面额都大于剩余金额」的目的,正确判断应该是min(coins) > amount- 可变默认参数
final_list=[]存在隐患:Python函数的默认参数在定义时初始化,多次调用会复用同一个列表对象,导致结果累计出错,建议改成final_list=None,在函数内部初始化空列表 - 贪心算法本身不适用所有零钱兑换场景:只有硬币面额满足「贪心选择性质」时才能得到最优解,比如硬币为
[1,3,4]、总金额为6时,贪心计算得到的结果是3枚(4+1+1),实际最优解是2枚(3+3),要得到通用正确结果建议用动态规划实现。
修复后的可运行贪心版本(仅适用于符合贪心性质的用例)
def coinChange(coins, amount, final_list=None): """ :type coins: List[int] :type amount: int :rtype: int """ if final_list is None: final_list = [] # 最小硬币面额都大于剩余金额,无法凑出 if min(coins) > amount: return -1 while amount > 0: max_val = max(coins) if amount - max_val >= 0: amount -= max_val final_list.append(max_val) else: coins.remove(max_val) return coinChange(coins, amount, final_list) return len(final_list) coins = [1,2,5] amount = 11 print(coinChange(coins, amount)) # 输出3,符合当前用例预期
内容的提问来源于stack exchange,提问作者Phani Teja
相关产品推荐
相关产品推荐

