剑指Offer 10 | LeetCode 509 斐波那契数列
斐波那契数列,经典中的经典,这里不做太多介绍了。
递归
常年作为循环的反面教材,时间复杂度以n的指数递增。
def fib(n):
if n <= 0: return 0
if n == 1: return 1
return fib(n-1) + fib(n-2)
循环
时间复杂度O(n)。
class Solution:
def fib(self, N: int) -> int:
fib1, fib2 = 0, 1
if N == 0: return 0
if N == 1: return 1
for i in range(2,N+1):
fib = fib2 + fib1
fib2, fib1 = fib, fib2
return fib2
剑指Offer 10.2 跳台阶 | LeetCode 70.爬楼梯
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
其实就是首项为1的Fibnacci数列。
class Solution:
def jumpFloor(self, number):
# write code here
fib1, fib2 = 1, 2
if number == 1: return 1
if number == 2: return 2
for i in range(3, number + 1):
fib = fib1 + fib2
fib2, fib1 = fib, fib2
return fib2
剑指Offer 10.3 变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
跳上第一级: 1
跳上第二级: 2
跳上第三级: 4
跳上第四级: 8
我们可以把跳上第4级看作5种途径:
从第0级直接跳到第4级,有1种方法;
从第1级直接跳到第4级,有1种方法;
从第2级直接跳到第4级,有2种方法;
从第3级直接跳到第4级,有4种方法;
加起来就是1+1+2+4 = 8,满足规律。
看似有点东西,然而O(n^2)的时间复杂度,O(n)的空间复杂度。
class Solution:
def jumpFloorII(self, number):
# write code here
if number < 1:
return - 1
res = [1,2]
for i in range(2, number):
temp = 1
for j in range(i):
temp += res[j]
res.append(temp)
return res[number - 1]
科学归纳法
其实在上一解法的基础上,可以用第一类数学归纳法求证第n级跳法有 f ( n ) = 2 n − 1 f(n)=2^{n-1} f(n)=2n−1:
n = 1时,f(1) = 2^(1-1) = 1, 命题成立。
假设n=k时命题也成立,即f(k) = 2^(k-1),
f(k+1) = f(k) + f(k-1) + ... + f(1) + 1,
其中f(k) = f(k-1) + f(k-2) + ... + f(1) + 1,
则有 f(k+1) = f(k) + f(k)
= 2^(k-1) + 2^(k-1)
= 2^(k) = 2^(k+1-1)
故命题成立。
时间复杂度O(n),空间复杂度O(1)。
class Solution:
def jumpFloorII(self, number):
# write code here
return pow(2,number - 1)