Ваш код в порядке, проблема находится в списке dp
. Когда вы выполняете [[-1]*len(coins)]*(amount+1)
в своем примере, сначала создается список [-1, -1, -1]
, затем он копируется (по ссылке) 501
раз. Когда вы изменяете любой элемент в любом из списков, все остальные списки также обновляются, что приведет к неверному результату.
Чтобы исправить это, либо создайте список, используя понимание списка:
dp = [[-1 for _ in range(len(coins))] for _ in range(amount+2)]
или используйте тот факт, что поиск dict
равен O(1)
в Python, и используйте dict
для мемоизации, чтобы избежать такой ошибки в будущем, например:
dp = {}
def changeHelper(amount, coins, index):
if amount == 0:
return 1
if index<0:
return 0
if (amount, index) in dp:
return dp[(amount, index)]
total_ways = 0
if amount>=coins[index]:
total_ways = changeHelper(amount-coins[index], coins, index)
total_ways += changeHelper(amount, coins, index-1)
dp[(amount, index)] = total_ways
return dp[(amount, index)]
РЕДАКТИРОВАТЬ:
Вот еще объяснение того, почему это произошло
>>> dp = [[-1] * 3] * 4
>>> dp
[[-1, -1, -1], [-1, -1, -1], [-1, -1, -1], [-1, -1, -1]]
>>> dp[0][0] = 5
>>> dp
[[5, -1, -1], [5, -1, -1], [5, -1, -1], [5, -1, -1]]
Подумайте об этом так: внутренний оператор создает:
tmp = [-1, -1, -1]
затем внешний:
dp = [tmp, tmp, tmp, tmp]