如何以递归方式递增列表中的第一个值并附加到python中的嵌套列表?

时间:2016-02-17 03:04:08

标签: python list recursion

我写了一个名为change的函数,它接收int和硬币列表。

它以递归方式检查创建该金额所需的最少金币数量并返回此数字。现在我正在尝试修改此功能以获取相同的输入,而是返回一个列表,其中包含硬币数量和使用的硬币列表。

def change(amount, coins):
    if amount == 0:
        return 0
    if coins == []:
        return float("inf")
    if coins[0] > amount:
        return change(amount, coins[1:])
    use_it = 1+change(amount-coins[0], coins)
    lose_it = change(amount, coins[1:])
    return min(use_it, lose_it)

我开始修改此代码但我不确定如何操作返回值,因为它是一个列表:

def giveChange(amount, coins):
    if amount == 0:
        return [0, []]
    if coins == []:
        return [float("inf"), []]
    if coins[0] > amount:
        return giveChange(amount, coins[1:])
    use_it = 1 + giveChange(amount-coins[0], coins)
    lose_it = giveChange(amount, coins[1:])
    listOfCoins = 
    return [min(use_it, lose_it), listOfCoins]

到目前为止,我有这个,但我的use_it行是错误的,因为该函数现在返回一个列表。我可以这么做吗:

use_it = 1 + giveChange(amount-coins[0], coins)[0]

我不知道如何建立硬币列表,以便我可以在最后用硬币返还它。

2 个答案:

答案 0 :(得分:2)

  

返回一个列表,其中包含硬币数量和使用的硬币列表。

我认为这就是你要找的东西:

def giveChange(amount, coins):
    if amount == 0:
        return [0, []]
    if coins == []:
        return [float("inf"), []]
    if coins[0] > amount:
        return giveChange(amount, coins[1:])
    [use_it_amt, use_it_list] = giveChange(amount-coins[0], coins)
    [lose_it_amt, lose_it_list] = giveChange(amount, coins[1:])
    if use_it_amt+1 < lose_it_amt:
        use_it_list.append(coins[0])
        return [use_it_amt+1, use_it_list]
    else:
        return [lose_it_amt, lose_it_list]

在这里你可以看到它有效:https://repl.it/Bn2T

因为这是动态编程,所以使用memoization表来防止重新计算子问题是好事,而且它依赖于堆栈,如果递归调用的数量太大,它会给你StackOverflow。

答案 1 :(得分:1)

只需在整个代码中正确处理第二个参数,唯一困难的是use_it需要在硬币数量上加1并将coin[0]添加到使用的硬币列表中。 min需要考虑并锁定第一个参数:

def give_change(amount, coins):
    if amount == 0:
        return [0, []]
    if coins == []:
        return [float('inf'), []]
    if coins[0] > amount:
        return give_change(amount, coins[1:])
    use_it = [x+y for x,y in zip(give_change(amount-coins[0], coins), [1,[coins[0]]])]
    lose_it = give_change(amount, coins[1:])
    return min(use_it, lose_it, key=lambda x: x[0])

>>> give_change(53, [1, 2, 5, 10, 25, 50, 100])
[3, [50, 2, 1]]

采用更加动态的编程方法,你可以在没有递归的情况下完成。我假设您可以重复使用硬币(因为您的原始代码也可以重复使用硬币)。 give_change现在返回所有可以通过硬币获得金额的方式,您只需min key=len

def give_change(amount, coins):
    ways = [list() for _ in range(0, amount+1)]
    ways[0].append([])

    for coin in coins:
        for i, x in enumerate(range(coin, amount+1)):
            ways[x].extend(l+[coin] for l in ways[i])
    return ways[amount]

>>> give_change(3, [1, 2, 5, 10, 25, 50, 100])
[[1, 1, 1], [1, 2]]
>>> min(give_change(3, [1, 2, 5, 10, 25, 50, 100]), key=len)
[1, 2]
>>> min(give_change(53, [1, 2, 5, 10, 25, 50, 100]), key=len)
[1, 2, 50]