|
| 1 | +// Question Link: https://leetcode.com/problems/memoize/?envType=study-plan-v2&envId=30-days-of-javascript |
| 2 | +// Solution Link: https://leetcode.com/problems/memoize/solutions/5435256/2-javascript-easy-solution/ |
| 3 | + |
| 4 | +/* |
| 5 | +2623. Memoize |
| 6 | +
|
| 7 | +Given a function fn, return a memoized version of that function. |
| 8 | +A memoized function is a function that will never be called twice with the same inputs. Instead it will return a cached value. |
| 9 | +You can assume there are 3 possible input functions: sum, fib, and factorial. |
| 10 | +sum accepts two integers a and b and returns a + b. Assume that if a value has already been cached for the arguments (b, a) where a != b, it cannot be used for the arguments (a, b). For example, if the arguments are (3, 2) and (2, 3), two separate calls should be made. |
| 11 | +fib accepts a single integer n and returns 1 if n <= 1 or fib(n - 1) + fib(n - 2) otherwise. |
| 12 | +factorial accepts a single integer n and returns 1 if n <= 1 or factorial(n - 1) * n otherwise. |
| 13 | + |
| 14 | +Example 1: |
| 15 | +Input: |
| 16 | +fnName = "sum" |
| 17 | +actions = ["call","call","getCallCount","call","getCallCount"] |
| 18 | +values = [[2,2],[2,2],[],[1,2],[]] |
| 19 | +Output: [4,4,1,3,2] |
| 20 | +Explanation: |
| 21 | +const sum = (a, b) => a + b; |
| 22 | +const memoizedSum = memoize(sum); |
| 23 | +memoizedSum(2, 2); // "call" - returns 4. sum() was called as (2, 2) was not seen before. |
| 24 | +memoizedSum(2, 2); // "call" - returns 4. However sum() was not called because the same inputs were seen before. |
| 25 | +// "getCallCount" - total call count: 1 |
| 26 | +memoizedSum(1, 2); // "call" - returns 3. sum() was called as (1, 2) was not seen before. |
| 27 | +// "getCallCount" - total call count: 2 |
| 28 | +
|
| 29 | +Example 2: |
| 30 | +Input: |
| 31 | +fnName = "factorial" |
| 32 | +actions = ["call","call","call","getCallCount","call","getCallCount"] |
| 33 | +values = [[2],[3],[2],[],[3],[]] |
| 34 | +Output: [2,6,2,2,6,2] |
| 35 | +Explanation: |
| 36 | +const factorial = (n) => (n <= 1) ? 1 : (n * factorial(n - 1)); |
| 37 | +const memoFactorial = memoize(factorial); |
| 38 | +memoFactorial(2); // "call" - returns 2. |
| 39 | +memoFactorial(3); // "call" - returns 6. |
| 40 | +memoFactorial(2); // "call" - returns 2. However factorial was not called because 2 was seen before. |
| 41 | +// "getCallCount" - total call count: 2 |
| 42 | +memoFactorial(3); // "call" - returns 6. However factorial was not called because 3 was seen before. |
| 43 | +// "getCallCount" - total call count: 2 |
| 44 | +
|
| 45 | +Example 3: |
| 46 | +Input: |
| 47 | +fnName = "fib" |
| 48 | +actions = ["call","getCallCount"] |
| 49 | +values = [[5],[]] |
| 50 | +Output: [8,1] |
| 51 | +Explanation: |
| 52 | +fib(5) = 8 // "call" |
| 53 | +// "getCallCount" - total call count: 1 |
| 54 | + |
| 55 | +Constraints: |
| 56 | +0 <= a, b <= 10^5 |
| 57 | +1 <= n <= 10 |
| 58 | +0 <= actions.length <= 10^5 |
| 59 | +actions.length === values.length |
| 60 | +actions[i] is one of "call" and "getCallCount" |
| 61 | +fnName is one of "sum", "factorial" and "fib" |
| 62 | +*/ |
| 63 | + |
| 64 | + |
| 65 | +/** |
| 66 | + * @param {Function} fn |
| 67 | + * @return {Function} |
| 68 | + */ |
| 69 | +function memoize(fn) { |
| 70 | + |
| 71 | + const cache = {}; |
| 72 | + |
| 73 | + return function(...args) { |
| 74 | + const key = args; |
| 75 | + |
| 76 | + if (key in cache) { |
| 77 | + return cache[key]; |
| 78 | + } |
| 79 | + |
| 80 | + const output = fn(...args); |
| 81 | + cache[key] = output; |
| 82 | + |
| 83 | + return output; |
| 84 | + } |
| 85 | +} |
| 86 | + |
| 87 | + |
| 88 | +/** |
| 89 | + * let callCount = 0; |
| 90 | + * const memoizedFn = memoize(function (a, b) { |
| 91 | + * callCount += 1; |
| 92 | + * return a + b; |
| 93 | + * }) |
| 94 | + * memoizedFn(2, 3) // 5 |
| 95 | + * memoizedFn(2, 3) // 5 |
| 96 | + * console.log(callCount) // 1 |
| 97 | + */ |
0 commit comments