力扣每日一题 - 记忆函数

127 阅读2分钟

题目

编写一个函数fn, 它接受另一个函数作为输入,并返回该函数的记忆化后的结果。

记忆函数是一个对于相同的输入永远不会被调用两次的函数。

相反,它将返回一个缓存值。

可以假设有3个可能的输入函数: sumfibfactorial

  • sum接收两个整型参数ab,并返回a+b。假设如果参数(b, a)已经缓存了值,其中a != b,它不能用于参数(a, b)。例如,如果参数是(3, 2)(2, 3),则应进行两个单独的调用。

  • fib接收一个整型参数n,如果n <= 1则返回1, 否则返回fib(n - 1) + fib(n - 2)

  • factorial接收一个整型参数n,如果n <= 1则返回1,否则返回factorial(n - 1)*n

例子

例子1


输入;

fnName = "sum"

actions = ['call', 'call', 'getCallCount', 'call', 'getCallCount']

values = [[2, 2], [2, 2], [], [1, 2], []]

输出:[4, 4, 1, 3, 2]


解释:

cosnt sum = (a, b) => a + b;

const memoizedSum = memoize(sum);

memoizedSum(2, 2); // 'call' - 返回4。sum()被调用,因为之前没有使用参数(2, 2)调用过。

memoizedSum(2, 2); // 'call' - 返回4。没有调用sum(),因为前面有相同的输入。

// "getCallCount" - 总调用数: 1

memoizedSum(1, 2); // 'call' - 返回3。sum()被调用,因为之前没有使用参数(1, 2)调用过。

// "getCallCount" - 总调用数: 2


例子2

输入:

fnName = "factorial"

actions = ['call', 'call', 'call', 'getCallCount', 'call', 'getCallCount']

values = [[2], [3], [2], [], [3], []]

输出: [2, 3, 2, 2, 6, 2]

解释:

const factorial = (n) => (n <= 1) ? 1 : (n * factorial(n - 1));
const memoFactorial = memoize(factorial);
memoFactorial(2); // 'call' - 返回2
memoFactorial(3); // 'call' - 返回6
memoFactorial(2); // 'call' - 返回2。没有调用factorial(), 因为前面有相同的输入。
// 'getCallCount' - 总调用数: 2

memoFactorial(3); // 'call' - 返回6。没有调用 factorial(), 因为前面有相同的输入。
// 'getCallCount' - 总调用数:2

例子3

输入:

fnName = 'fib'

actions = ['call', 'getCallCount']

values = [[5], []]

输出: [8, 1]

解释:

fib(5) = 8 // 'call'

// "getCallCout" - 总调用数: 1


/**
 * @param {Function} fn
 * @return {Funciton}
**/
function memoize(fn) {
    
    return function(...args) {
        
    }
    
}


// 下面是对这个memoize 函数的解释

/**
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
**/

解题:

function memoize(fn) {
    const map = new Map()
    return function(...args) {
        const item = args.join(',')
        if (!map.has(item)) {
            map.set(item, fn(...args))
        }
        return map.get(item)
    }
}