You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归实现硬币找零:如何将结果改为列表的列表形式?

我来帮你搞定这个问题!原代码的问题在于它把所有硬币都扁平地拼在一个列表里,还混入了无效的-1,完全没区分开不同的找零方案。咱们得调整递归的思路,改成收集每一条完整的有效路径,最终输出列表的列表格式。

修改后的实现思路

我们用回溯法来实现:通过递归尝试每一种硬币组合,当剩余金额刚好减到0时,就把当前的找零路径存入结果列表;如果剩余金额小于0,就直接回退,放弃这条无效路径。

完整代码

def coin_change(coins, target):
    # 用来存储所有有效找零方案的大列表
    result = []
    
    def backtrack(remaining, current_path):
        # 剩余金额为0,说明找到一个有效方案,存入结果
        if remaining == 0:
            # 必须复制当前路径,避免后续修改影响已存入的结果
            result.append(current_path.copy())
            return
        # 剩余金额小于0,这条路走不通,直接返回
        if remaining < 0:
            return
        # 遍历每个硬币,尝试加入当前路径
        for coin in coins:
            current_path.append(coin)
            # 递归处理减去当前硬币后的剩余金额
            backtrack(remaining - coin, current_path)
            # 回溯:移除刚加入的硬币,尝试下一个硬币
            current_path.pop()
    
    # 启动回溯,初始剩余金额是目标值,路径为空
    backtrack(target, [])
    return result

# 测试你的示例
coins = [3,10,7]
target = 5
print(coin_change(coins, target))  # 输出:[](因为3、7、10都无法凑出5)

额外优化:避免重复方案

如果觉得[1,2,2]和[2,1,2]属于同一种找零方案(只是顺序不同),可以调整递归逻辑,让每个方案只按硬币的原有顺序组合,避免重复。修改后的回溯函数如下:

def backtrack(remaining, current_path, start_index):
    if remaining == 0:
        result.append(current_path.copy())
        return
    if remaining < 0:
        return
    # 从start_index开始遍历,只选当前及之后的硬币,避免顺序不同的重复方案
    for i in range(start_index, len(coins)):
        coin = coins[i]
        current_path.append(coin)
        backtrack(remaining - coin, current_path, i)
        current_path.pop()

# 启动时start_index设为0
backtrack(target, [], 0)

比如用coins=[1,2,5]、target=5测试,优化后的输出会是:

[[1,1,1,1,1], [1,1,1,2], [1,2,2], [5]]

内容的提问来源于stack exchange,提问作者Vidya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:15:59