【问题标题】:LeetCode #70 Climbing Stairs, How to speed up my solution?LeetCode #70 爬楼梯,如何加快我的解决方案?
【发布时间】:2020-08-19 15:36:06
【问题描述】:

我在 LeetCode #70 爬楼梯上有这个问题的解决方案,我的解决方案没有通过,因为它很慢......

我已经添加了一个使用 thunk 的蹦床,并且我已经添加了记忆,我还可以添加什么来加速它以实际通过我的代码在下面的这个问题的时间要求,并提前致谢。

关于 LeetCode 的描述:

你正在爬楼梯。到达顶部需要 n 步。

每次您可以爬 1 或 2 级台阶。您可以通过多少种不同的方式登顶?

注意:给定 n 将是一个正整数。

Example 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps


Example 2:

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

LeetCode 上的问题链接:https://leetcode.com/problems/climbing-stairs/


let cache = {};

const sumStairSteps = arr => arr.reduce((acc, cur) => acc + cur, 0);

const thunk = (fn, ...args) => {
    return () => fn(...args);
}

const climbStairsHelper2 = fn => {

    let thunk = fn();

    while (typeof thunk === "function") {
        thunk = thunk();
    }

    return thunk;
};

const climbStairs2 = (newStairSequence, ladderCount) => {
    const sum = sumStairSteps(newStairSequence);

    if (sum === ladderCount) {  cache[ladderCount] = cache[ladderCount] + 1; }


    if (1 + sum <= ladderCount) {
        climbStairsHelper2(thunk(climbStairs2, [ ...newStairSequence, 1 ], ladderCount));
    }

    if (2 + sum <= ladderCount) {
         climbStairsHelper2(thunk(climbStairs2, [ ...newStairSequence, 2 ], ladderCount));
    }
};

const climbStairs = n => {
        if (n in cache) return cache[n];
        cache[n] = 0;
        climbStairs2([], n);
        console.log(cache[n]);
        return cache[n];
};

【问题讨论】:

  • 你到底想在这里做什么?
  • 我正在尝试提高解决方案的速度。
  • 不,我的意思是,您能解释一下您发布的代码的用途吗?
  • 我正在使用带有递归的记忆,我也在使用带有 thunk 的蹦床以避免堆栈溢出异常。
  • 但是你真正想要解决的问题是什么?

标签: javascript recursion optimization dynamic-programming trampolines


【解决方案1】:

我不太遵循您在此处使用的方法。问题实际上非常简单:编写朴素的递归解决方案,然后memoize 结果。也就是说,如果您访问缓存中的楼梯,则返回它,否则计算它。运行时是线性的。

const climbStairs = (goal, curr=0, memo={}) => {
  if (goal < curr) {
    return 0;
  }
  else if (goal === curr) {
    return 1;
  }
  else if (curr in memo) {
    return memo[curr];
  }
  
  return memo[curr] = climbStairs(goal, curr + 1, memo) +
                      climbStairs(goal, curr + 2, memo);
};

console.log(climbStairs(50));

【讨论】:

  • 是否有办法让我的解决方案更加优化?
  • 当然,您可以放弃 thunk、传播、求和、额外的助手和其他不必要的步骤,并像我在这里展示的那样在备忘录上拍打,但我不确定这有多大的指导意义,它似乎等同于重写。换句话说,我没有看到一种明显的方法来修复代码,但我也不太了解基本方法。
  • 是的,我基本上不得不把它扔进垃圾桶然后重做......
【解决方案2】:

好的,所以您希望解决方案更加优化。

您目前正在讨论的解决方案具有线性运行时间,即 O(N),并且在 LeetCode 上被接受。 现在我们先不讨论空间复杂度。

这个问题和这些问题的一个类别可以通过一种称为矩阵求幂的方法来解决,该方法具有对数运行时间,即 O(Log N)

这个链接很好地描述了矩阵求幂

https://discuss.codechef.com/t/building-up-the-recurrence-matrix-to-compute-recurrences-in-o-logn-time/570

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多