2016-08-16 4 views
0

私の再帰coinSums:Memoize私は基本<code>coinSums</code>再帰関数を持っている

function coinSums(total) {  
    var coins = [1, 5, 10, 25]; 
    var output = []; 
    var memo={} <--the only part im sure about :) 
    function subroutine(pos, runningSum, currentCombo) { 
     if (total === runningSum) { 
      return output.push(currentCombo) 
     } else if (total < runningSum) { 
      return false 
     } else 
      for (var i = pos; i < coins.length; i++) { 
       subroutine(i, runningSum + coins[i], currentCombo.concat(coins[i])) 
      } 
    } 
    subroutine(0, 0, []) 
    return output.length; } 

私は本当に(?右、k=num of coinsn=target)それはO(n^k)ランタイムを改善する方法「memoize」を把握したいと思いますが、 を再帰的に保ち、できるだけ再帰呼び出しを変更しないでください。 (私はコンボを維持する必要があり、runningSumボトムアップ アプローチ)。

私はトップダウンアプローチでそれを行う方法を知っています。どんな天才 もありますか?

PS私たちは私たちに命じた組み合わせの数を与えるために0にでforループ 着工のposそのiを変更することができます。私は、 コンボを実行し続けることを望んでいるので、順序のないコンボを返すためには が必要です。

+1

memoizationは、以前は同じ引数で呼び出された場合に*再帰を防ぐことができるという点で、動的プログラミングの基本的なテクニックです。あなたは再帰を保つことを好むと述べましたが、動的プログラミングではありません。 –

+0

私はこの問題を知りませんが、この問題を解決するにはBit Maskingアプローチを使用するべきだと思います。 –

+0

1. memoizationを探している場合は、リンクhttps://addyosmani.com/blog/faster-javascript-memoization/2にアクセスしてください。JSでは関数もオブジェクトであるため、新しいオブジェクトを宣言する必要はありません値をキャッシュします。代わりに、現在の入力の出力を格納するためにfunctionName [input]を使用することができます。 3. var memo = {}は、特定の入力の結果を格納/キャッシュするオブジェクトです。 – Jay

答えて

0

私はあなたの要件は、あなたが coinSums自体のmuliple用途にメモ化を使用する場合を除き満たすことは不可能である怖いです - あなたは常に異なる引数セットでsubroutine を呼び出している元の単一のアプリケーションでは、と私はそれがアルゴリズム全体の核心であるので、私が「メモから除外する」ことができないと信じているcurrentComboです。

これを収集することは、このトップダウン再帰を使って、これはおそらくあなたが知っているものですが、メモ作成のために "いい"です。

function coinSums(total) { 
    /// "cache": 
    var _coinSumsMem_ = {}; 
    var lookupCoins = function(total,pos) { 
     return _coinSumsMem_[[total,pos]]; 
    }; 
    var memoizeCoins=function(total,pos, coins) { 
     _coinSumsMem_[[total,pos]] 
      = coins.map(function(xs) {return xs.slice();}); /// a clone! 
    }; 
    /// "computation": 
    var coinsAvailable = [1,5,10,20];  
    findAll = function(total, pos) { 
     if(total<0 || pos==coinsAvailable.length) return []; 
     else if(total==0) return [[]]; 
     var result = lookupCoins(total,pos); 
     if(result == undefined) { 
      var oneWaySums = findAll(total-coinsAvailable[pos], pos); 
      oneWaySums.map(function(xs) {xs.push(coinsAvailable[pos]);}); 
      var otherWaySums = findAll(total, pos+1); 
      result = oneWaySums.concat(otherWaySums); 
      memoizeCoins(total,pos, result); 
     } 
     return result; 
    }; 
    return findAll(total,0).length; /// or without length... 
} 
+0

私は考えました。しかし、助けと考えてくれてありがとう! – BYC

関連する問題