diff --git a/_posts/development/algorithm/leetCode/2024-04-15-algorithm-leetcode-Apply-Transform-Over-Each-Element-in-Array.md b/_posts/development/algorithm/leetCode/2024-04-15-algorithm-leetcode-Apply-Transform-Over-Each-Element-in-Array.md index b076566..72b55be 100644 --- a/_posts/development/algorithm/leetCode/2024-04-15-algorithm-leetcode-Apply-Transform-Over-Each-Element-in-Array.md +++ b/_posts/development/algorithm/leetCode/2024-04-15-algorithm-leetcode-Apply-Transform-Over-Each-Element-in-Array.md @@ -26,6 +26,8 @@ Please solve it without the built-in Array.map method. ### **Example** +--- + Example 1: > Input: arr = [1,2,3], fn = function plusone(n) { return n + 1; } diff --git a/_posts/development/algorithm/leetCode/2024-04-17-algorithm-leetcode-Filter-Elements-from-Array.md b/_posts/development/algorithm/leetCode/2024-04-17-algorithm-leetcode-Filter-Elements-from-Array.md index b88d9b1..63172af 100644 --- a/_posts/development/algorithm/leetCode/2024-04-17-algorithm-leetcode-Filter-Elements-from-Array.md +++ b/_posts/development/algorithm/leetCode/2024-04-17-algorithm-leetcode-Filter-Elements-from-Array.md @@ -31,6 +31,8 @@ Please solve it without the built-in Array.filter method. ### **Example** +--- + Example 1: > Input: arr = [0,10,20,30], fn = function greaterThan10(n) { return n > 10; } diff --git a/_posts/development/algorithm/leetCode/2024-04-20-algorithm-leetcode-Array-Reduce-Transformation copy.md b/_posts/development/algorithm/leetCode/2024-04-20-algorithm-leetcode-Array-Reduce-Transformation copy.md index a206909..db04f25 100644 --- a/_posts/development/algorithm/leetCode/2024-04-20-algorithm-leetcode-Array-Reduce-Transformation copy.md +++ b/_posts/development/algorithm/leetCode/2024-04-20-algorithm-leetcode-Array-Reduce-Transformation copy.md @@ -28,6 +28,8 @@ Please solve it without using the built-in Array.reduce method. ### **Example** +--- + Example 1: > Input: diff --git a/_posts/development/algorithm/leetCode/2024-04-22-algorithm-Function-Composition copy.md b/_posts/development/algorithm/leetCode/2024-04-22-algorithm-Return-Length-of-Arguments-Passed.md similarity index 99% rename from _posts/development/algorithm/leetCode/2024-04-22-algorithm-Function-Composition copy.md rename to _posts/development/algorithm/leetCode/2024-04-22-algorithm-Return-Length-of-Arguments-Passed.md index 9dd0696..f07dce4 100644 --- a/_posts/development/algorithm/leetCode/2024-04-22-algorithm-Function-Composition copy.md +++ b/_posts/development/algorithm/leetCode/2024-04-22-algorithm-Return-Length-of-Arguments-Passed.md @@ -22,6 +22,8 @@ Write a function argumentsLength that returns the count of arguments passed to i ### **Example** +--- + Example 1: > Input: args = [5] diff --git a/_posts/development/algorithm/leetCode/2024-04-23-algorithm-Function-Composition.md b/_posts/development/algorithm/leetCode/2024-04-23-algorithm-Function-Composition.md index 5ae4bf5..31f37ef 100644 --- a/_posts/development/algorithm/leetCode/2024-04-23-algorithm-Function-Composition.md +++ b/_posts/development/algorithm/leetCode/2024-04-23-algorithm-Function-Composition.md @@ -28,6 +28,8 @@ You may assume each function in the array accepts one integer as input and retur ### **Example** +--- + Example 1: diff --git a/_posts/development/algorithm/leetCode/2024-04-24-algorithm-Allow-One-Function-Call.md b/_posts/development/algorithm/leetCode/2024-04-24-algorithm-Allow-One-Function-Call.md index fb9d64d..bb64b4e 100644 --- a/_posts/development/algorithm/leetCode/2024-04-24-algorithm-Allow-One-Function-Call.md +++ b/_posts/development/algorithm/leetCode/2024-04-24-algorithm-Allow-One-Function-Call.md @@ -25,6 +25,8 @@ Given a function fn, return a new function that is identical to the original fun ### **Example** +--- + Example 1: > Input: fn = (a,b,c) => (a + b + c), calls = [[1,2,3],[2,3,6]] diff --git a/_posts/development/algorithm/leetCode/2024-04-25-algorithm-Memoize.md b/_posts/development/algorithm/leetCode/2024-04-25-algorithm-Memoize.md new file mode 100644 index 0000000..43597cd --- /dev/null +++ b/_posts/development/algorithm/leetCode/2024-04-25-algorithm-Memoize.md @@ -0,0 +1,140 @@ +--- +layout: post +title: '[LeetCode] Memoize' +subtitle: '[LeetCode] Memoize' +category: dev +tag: algorithm +image: + path: /assets/img/algorithm.png +--- + + +* this ordered seed list will be replaced by the toc +{:toc} + +## PROBLEMS + +### **Description** + +--- + +Given a function fn, return a memoized version of that function. + +A memoized function is a function that will never be called twice with the same inputs. Instead it will return a cached value. + +You can assume there are 3 possible input functions: sum, fib, and factorial. + +- 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. + +- fib accepts a single integer n and returns 1 if n <= 1 or fib(n - 1) + fib(n - 2) otherwise. + +- factorial accepts a single integer n and returns 1 if n <= 1 or factorial(n - 1) \* n otherwise. + +### **Example** + +--- + +Example 1: + +> Input: +> fnName = "sum" +> actions = ["call","call","getCallCount","call","getCallCount"] +> values = [[2,2],[2,2],[],[1,2],[]] +> Output: [4,4,1,3,2] +> Explanation: +> const sum = (a, b) => a + b; +> const memoizedSum = memoize(sum); +> memoizedSum(2, 2); // "call" - returns 4. sum() was called as (2, 2) was not seen before. +> memoizedSum(2, 2); // "call" - returns 4. However sum() was not called because the same inputs were seen before. +> // "getCallCount" - total call count: 1 +> memoizedSum(1, 2); // "call" - returns 3. sum() was called as (1, 2) was not seen before. +> // "getCallCount" - total call count: 2 + +Example 2: + + +> Input: +> fnName = "factorial" +> actions = ["call","call","call","getCallCount","call","getCallCount"] +> values = [[2],[3],[2],[],[3],[]] +> Output: [2,6,2,2,6,2] +> Explanation: +> const factorial = (n) => (n <= 1) ? 1 : (n * factorial(n - 1)); +> const memoFactorial = memoize(factorial); +> memoFactorial(2); // "call" - returns 2. +> memoFactorial(3); // "call" - returns 6. +> memoFactorial(2); // "call" - returns 2. However factorial was not called because 2 was seen before. +> // "getCallCount" - total call count: 2 +> memoFactorial(3); // "call" - returns 6. However factorial was not called because 3 was seen before. +> // "getCallCount" - total call count: 2 + +Example 3: + +> Input: +> fnName = "fib" +> actions = ["call","getCallCount"] +> values = [[5],[]] +> Output: [8,1] +> Explanation: +> fib(5) = 8 // "call" +> // "getCallCount" - total call count: 1 + +### **Constraints** + +--- + +- 0 <= a, b <= 105 +- 1 <= n <= 10 +- 0 <= actions.length <= 105 +- actions.length === values.length +- actions[i] is one of "call" and "getCallCount" +- fnName is one of "sum", "factorial" and "fib" + +### Solution + +--- + +- Runtime: 366ms +- Memory: 85.91MB + +``` +/** + * @param {Function} fn + * @return {Function} + */ +function memoize(fn) { + const cache = {} + return function (...args) { + if(args in cache) { + return cache[args] + } + const getValue = fn(...args) + cache[args] = getValue + return getValue + } +} + + +/** + * let callCount = 0; + * const memoizedFn = memoize(function (a, b) { + * callCount += 1; + * return a + b; + * }) + * memoizedFn(2, 3) // 5 + * memoizedFn(2, 3) // 5 + * console.log(callCount) // 1 + */ +``` + +### Retrospect + +--- + +문제의 설명은 `memozie`함수가 아닌 inner함수(`return function(...arge){}`)를 여러번 호출하게 될 경우 동일한 파라미터를 넘겨주게 되면 `memoize`함수를 실행하지 않는 것이었고, 이전에 들어왔던 **동일한 값**을 캐싱하고 있다가 반환해주는 것이었다. 그래서 나는 outer함수인 `memozie`함수에 `cache`라는 변수를 하나 선언해두고 해당 변수에 값을 캐싱하여 동일한 값이 들어오면 캐싱 된 값을 반환을 했다. + +if 조건문을 통해 `cache`의 속성에 파라미터로 넘어온 args가 존재하게 되면, 캐싱된 값을 리턴하게 했다. 그게 아니라면 `memozie`함수를 호출하여 값을 얻은 값을 cache에 args가 키를 가지도록 해서 넣어주었고, 함수 실행을 통해 얻은 값을 반환했다. + +이번 문제는 생각보다 시간이 오래걸렸는데 자꾸 실행을하니 getCallCount가 자꾸 함수를 실행한만큼 나오는 것이었다. 나는 함수를 실행시키고 추출해서 나온 동일한 값에 대해서만 조건을 주고 캐싱된 값을 반환하고 있었는데 문제를 다시 읽어보니, **A memoized function is a function that will never be called twice with the same inputs**라는 문구가 눈에 띄었다. + +실제로 함수를 메모이제이션해서 호출되지 않게끔 해야했었다. `useMemo`, `useCallBack`과 동일한 개념이 사용되었다. 이렇게 메모이제이션해서 사용하게 되면 메모리가 절약되기 때문에 성능상 유리한 측면이 있다고 생각된다.