70. Climb stairs

70_solution1_memo.c

#include <stdlib.h>

static int ways(int i, int *memo) {
  if (i <= 2)
    return i; // ways(1) = 1, ways(2) = 2
  if (memo[i] != -1)
    return memo[i];
  return memo[i] = ways(i - 1, memo) + ways(i - 2, memo);
}

int climbStairs(int n) {
  int *memo = malloc((n + 1) * sizeof(int));
  for (int i = 0; i <= n; i++)
    memo[i] = -1;
  int res = ways(n, memo);
  free(memo);
  return res;
}

70_solution2_tab.c

#include <stdlib.h>

int climbStairs(int n) {
  if (n <= 2)
    return n;

  int *dp = malloc((n + 1) * sizeof(int));
  dp[1] = 1;
  dp[2] = 2;

  for (int i = 3; i <= n; i++) {
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  int res = dp[n];
  free(dp);
  return res;
}

70_solution1_memo.cpp

#include <vector>

using namespace std;

class Solution {
  vector<int> memo;

  int ways(int i) {
    if (i <= 2)
      return i; // ways(1) = 1, ways(2) = 2
    if (memo[i] != -1)
      return memo[i];
    return memo[i] = ways(i - 1) + ways(i - 2);
  }

public:
  int climbStairs(int n) {
    memo.assign(n + 1, -1);
    return ways(n);
  }
};

70_solution2_tab.cpp

#include <vector>

using namespace std;

class Solution {
public:
  int climbStairs(int n) {
    if (n <= 2)
      return n;

    vector<int> dp(n + 1);
    dp[1] = 1;
    dp[2] = 2;

    for (int i = 3; i <= n; i++) {
      dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
  }
};

70_solution1_memo.go

package dp

func climbStairs(n int) int {
    memo := make([]int, n+1)

    var ways func(i int) int
    ways = func(i int) int {
        if i <= 2 {
            return i // ways(1) = 1, ways(2) = 2
        }
        if memo[i] != 0 {
            return memo[i]
        }
        memo[i] = ways(i-1) + ways(i-2)
        return memo[i]
    }

    return ways(n)
}

70_solution2_tab.go

package dp

func climbStairs(n int) int {
    if n <= 2 {
        return n
    }

    dp := make([]int, n+1)
    dp[1], dp[2] = 1, 2

    for i := 3; i <= n; i++ {
        dp[i] = dp[i-1] + dp[i-2]
    }
    return dp[n]
}

70_solution1_memo.java

import java.util.Arrays;

class Solution {
    private int[] memo;

    private int ways(int i) {
        if (i <= 2)
            return i; // ways(1) = 1, ways(2) = 2
        if (memo[i] != -1)
            return memo[i];
        return memo[i] = ways(i - 1) + ways(i - 2);
    }

    public int climbStairs(int n) {
        memo = new int[n + 1];
        Arrays.fill(memo, -1);
        return ways(n);
    }
}

70_solution2_tab.java

class Solution {
    public int climbStairs(int n) {
        if (n <= 2)
            return n;

        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;

        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

70_solution1_memo.js

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function (n) {
  const memo = new Array(n + 1).fill(-1);

  const ways = (i) => {
    if (i <= 2) return i; // ways(1) = 1, ways(2) = 2
    if (memo[i] !== -1) return memo[i];
    return (memo[i] = ways(i - 1) + ways(i - 2));
  };

  return ways(n);
};

70_solution2_tab.js

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function (n) {
  if (n <= 2) return n;

  const dp = new Array(n + 1);
  dp[1] = 1;
  dp[2] = 2;

  for (let i = 3; i <= n; i++) {
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  return dp[n];
};

70_solution1_memo.py

class Solution:
    def climbStairs(self, n: int) -> int:
        memo = [-1] * (n + 1)

        def ways(i: int) -> int:
            if i <= 2:
                return i  # ways(1) = 1, ways(2) = 2
            if memo[i] != -1:
                return memo[i]
            memo[i] = ways(i - 1) + ways(i - 2)
            return memo[i]

        return ways(n)

70_solution2_tab.py

class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 2:
            return n

        dp = [0] * (n + 1)
        dp[1], dp[2] = 1, 2

        for i in range(3, n + 1):
            dp[i] = dp[i - 1] + dp[i - 2]
        return dp[n]

70_solution1_memo.rs

impl Solution {
    pub fn climb_stairs(n: i32) -> i32 {
        let n = n as usize;
        let mut memo = vec![-1; n + 1];
        Self::ways(n, &mut memo)
    }

    fn ways(i: usize, memo: &mut Vec<i32>) -> i32 {
        if i <= 2 {
            return i as i32; // ways(1) = 1, ways(2) = 2
        }
        if memo[i] != -1 {
            return memo[i];
        }
        memo[i] = Self::ways(i - 1, memo) + Self::ways(i - 2, memo);
        memo[i]
    }
}

70_solution2_tab.rs

impl Solution {
    pub fn climb_stairs(n: i32) -> i32 {
        let n = n as usize;
        if n <= 2 {
            return n as i32;
        }

        let mut dp = vec![0; n + 1];
        dp[1] = 1;
        dp[2] = 2;

        for i in 3..=n {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        dp[n]
    }
}