4 回答

TA貢獻1785條經驗 獲得超8個贊
這里發生了幾件事。
首先是 的行為coins[coins.length - 1]。在 Javascript 中,當您在該列表中不存在的索引處訪問列表的元素時,索引器將返回undefined而不是與 anIndexOutOfBoundsException或類似內容一起崩潰。
二是qty * currentCoin <= amount。在currentCoin未定義的情況下(由于上述原因),qty * currentCoin將為NaN. 在 Javascript 中,任何NaN與另一個數字的比較都會按設計返回 false。(例如NaN <= anything是假的)。
把這一切放在一起,你會看到,在第一次遞歸時,coins數組將為空,這使得currentCoinNaN。這會導致qty * currentCoin <= currentAmount錯誤,從而導致循環短路(因此slice永遠不會在空列表上調用)。由于循環永遠不會執行,total因此仍將為 0,這就是返回的內容。這一直持續到qty * currentCoin <= amount在最外層遞歸中變為真,并且該循環退出時total仍然等于 0(因為它只添加了 0)。
如果您console.log在有關該功能的戰略位置散布調用,那么正在發生的事情會變得更加清晰:
var change = function(amount, coins) {
console.log(amount, coins);
if(amount == 0) return 1;
let currentCoin = coins[coins.length - 1];
console.log(':', currentCoin, amount);
let total = 0;
for(let qty = 0; qty * currentCoin <= amount; qty++){
total += change(amount - qty * currentCoin, coins.slice(0, -1))
console.log('=', total);
}
console.log('recdone');
return total;
};
console.log(change(3,[2]))

TA貢獻1829條經驗 獲得超7個贊
var change = function(amount, coins) {
if(amount == 0) return 1;
let currentCoin = coins[coins.length - 1]; // firstpass 1-1 = 0, second pas 0-1=-1 => coins[-1] = undefined
let total = 0;
// this will 0*0<=3, second pass 0*undefined => null which is false hence never execute
for(let qty = 0; qty * currentCoin <= amount; qty++){
total += change(amount - qty * currentCoin, coins.slice(0, -1))
}
return total;
};
console.log(change(3,[2]))
在第二遍時,coins.length = 0 然后
let currentCoin = coins[0 - 1]; // = undefined
稍后在 for 循環中,您將 0 * undefined ( qty * currentCoin) 導致 NaN 不是數字

TA貢獻1817條經驗 獲得超6個贊
不會崩潰,因為與數字相比,NaN 都是錯誤的... NaN < number or NaN > number 等等都會產生錯誤...所以
qty * currentCoin <= amount
評估為 false 并將從 for 中退出。
所以,如果你需要檢查 NaN 你必須在 for
let totalCoin = qty * currentCoin;
let check = isNaN(totalCoin);
if(check) {
// return you sentinel value;
}

TA貢獻1825條經驗 獲得超4個贊
在這種情況下不需要遞歸??梢允褂米韵露系膭討B規劃方法。讓ways[i]表示i用給定硬幣獲得美元的方式數量,并coins[i]表示i第 th 個硬幣的價值。然后,是從 1 到硬幣數量的所有ways[i]的總和。ways[i - coins[j]]j
var change = function(amount, coins) {
const ways = Array(amount + 1);
ways[0] = 1;
for(const coin of coins){
for(let i = coin; i <= amount; i++){
ways[i] = (ways[i] ?? 0) + ways[i - coin] ?? 0;
}
}
return ways[amount];
};
console.log(change(5,[1,2,3,4,5]))
添加回答
舉報