LeetCode刷题——爬楼梯(多种方法求解)

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:输入:n = 2 输出:2
示例 2:输入:n = 7 输出:21

class Solution {
  	int[] dy;
	int mod = 1000000007;

	public int numWays(int n) {
		dy = new int[n];
		Arrays.fill(dy, -1);
		int sum = 0;
		sum = DFS(n, 1);
		return sum;
	}

	public int DFS(int n, int level) {
		if (level >= n) {
			return 1;
		} else {
			if (dy[level] != -1) {
				return dy[level];
			} else {
				dy[level] = DFS(n, level + 1) % mod + DFS(n, level + 2) % mod;
				return dy[level] % mod;

			}
		}
	}
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

更新:添加几种解决的方法

第一种: 递归(但会重复计算),时间复杂度高,会超时,适用于小数范围

public int climbStairs(int n) {
		if (n <= 2) {
			return n == 1 ? 1 : 2;
		}
		return climbStairs(n - 1)  + climbStairs(n - 2) ;
	}

第二种:记忆化递归(解决重复计算)

	public int climbStairs2(int n) {
		int[] memo = new int[n + 1];
		return memory(n, memo);
	}

	public int memory(int n, int[] memo) {
		if (memo[n] > 0) {
			return memo[n];
		}
		if (n <= 2) {
			return n == 1 ? 1 : 2;
		} else {
			memo[n] = memory(n - 1, memo) + memory(n - 2, memo);
		}
		return memo[n];
	}

另一种版本(跟最上面的方法差不多的步骤,此处的更简洁明了)

// 记忆化递归2
	int[] dp;

	public int climbStairs3(int n) {
		dp = new int[n];
		Arrays.fill(dp, -1);
		return DFS(n, 0);
	}

	public int DFS(int n, int level) {
		if (level >= n) {
			return level == n ? 1 : 0;
		}
		if (dp[level] != -1) {
			return dp[level];
		} else {
			dp[level] = DFS(n, level + 1) + DFS(n, level + 2);
		}
		return dp[level];
	}

第三种:动态规划 

// 动态规划
	public int climbStairs3(int n) {
		/*
		 * 考虑数组的长度 如果n=1,那么dp数组的长度为2,下面设置的dp[2]=2就会报错:超出范围
		 * 如果n=2,那么dp数组的长度为3,dp[2]不会报错 所以n>1的情况,可以直接用dp 要考虑特殊情况,题目要求为正整数(>0)
		 * 细节决定成败
		 */
		if (n == 1) {
			return 1;
		}
		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];
	}

第四种:Fibonacci数列(迭代)

// Fibonacci
	public int climbStairs5(int n) {
		if (n <= 2) {
			return n == 1 ? 1 : 2;
		}
		int a = 1, b = 2, count = 0;
		while (count <= n) {
			int c = a + b;
			a = b;
			b = c;
			count++;
		}
		return b;
	}

另一种版本:

// Fibonacci2
	public int climbStairs6(int n) {
		int a = 0, b = 0, c = 1;
		for (int i = 1; i <= n; i++) {
			a = b;
			b = c;
			c = a + b;
		}
		return c;
	}

还有方法,不再赘述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值