二刷LeetCode70.爬楼梯(四种解法)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

题目分析,找规律

n=1:一级台阶,只有1种方法
n=2:两级台阶,可以一级一级爬,也可以一次爬两级,2种方法
n=3:一级一级、第一次爬两级,后一级、第一次一级,后两级,共三种方法
以此类推可以得到公式:Fn=Fn-1+Fn-2
(我们可以倒着从顶往下看:第n级台阶,可以是从第n-1级开始爬一级或者从第n-2级爬2级)

解法一:递归(适用于较小范围)

会重复计算:

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

解法二:记忆化递归(解决递归的重复计算)

(两种形式的代码)

// 记忆化递归1
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 - 1, memo);
	}
	return memo[n];
}
// 记忆化递归2
int[] dp;

public int climbStairs3(int n) {
	dp = new int[n];
	return DFS(n, 0);
}

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

解法三:动态规划

// 动态规划
public int climbStairs4(int n) {
	if (n <= 2) {
		return n == 1 ? 1 : 2;
	}
	int[] dp = new int[n];
	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 = 3;
	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;
}

end.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值