You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the fewest number
of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
You may assume that you have an infinite number
of each kind of coin.
Example 1:
Input: coins = [1,2,5], amount = 11Output: 3Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3Output: -1
Example 3:
Input: coins = [1], amount = 0Output: 0
描述中有两个关键信息
fewest number
:意味着应用最大的数字来逆序放入背包。infinite number
: 意味着背包中可以重复的数字。以 nums = [1,2,5]
为例进行分析:
dp[i] 的语义:在 nums 数组中挑选若干个值(可重复挑选),使它们之和为 i。
每一行分别
背包容量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
-1 | 1 | 1 | 3 | 2 | 1 | 2 | 2 | 3 | 3 | 2 | 3 |
/*** @param {number[]} coins* @param {number} amount* @return {number}*/var coinChange = function(coins, amount) {const sortedArr = coins.sort((a, b) => b - a)const deDuplicate = Array.from(new Set(sortedArr))let count = 0let extra = amountfor (let i = 0; i < deDuplicate.length; i++) {while (extra > 0) {extra = extra - deDuplicate[i]count = count + 1}if (extra === 0) {return count} else {if (i === deDuplicate.length - 1) return -1extra = extra + deDuplicate[i]count = count - 1}}return count}
[186,419,83,408]6249输出:-1预期结果:20
递归
/*** @param {number[]} coins* @param {number} amount* @return {number}*/var coinChange = function(coins, amount) {const sortedArr = coins.sort((a, b) => b - a)const deDuplicate = Array.from(new Set(sortedArr))if (amount === 0) return 0return recursive(deDuplicate, amount, {}, 0)}var recursive = function(arr, extra, cache, count) {if (count > cache[extra]) returnif (count <= cache[extra]) {cache[extra] = count}let result// the problem is once return then extra loop logic can't be performed.for (let i = 0; i < arr.length; i++) {const extraVal = extra - arr[i]const recursiveVal = recursive(arr, extraVal, cache, count + 1)}return result || -1}
try
/*** @param {number[]} coins* @param {number} amount* @return {number}*/var coinChange = function(coins, amount) {const sortedArr = coins.sort((a, b) => b - a)const deDuplicate = Array.from(new Set(sortedArr))if (amount === 0) return 0const cache = {}recursive(deDuplicate, amount, cache, 0)return cache.count ? cache.count : -1}var recursive = function(arr, extra, cache, count) {if (extra < 0) returnif (extra === 0) {cache.count = countreturn}for (let i = 0; i < arr.length; i++) {if (cache.count) returnrecursive(arr, extra - arr[i], cache, count + 1)}}