爬楼梯算法的数学思路
今日腾讯实习面试,问到一题算法。
爬楼梯问题:一个楼梯一共n个台阶,一次上1或者2个台阶。问,一共多少种解法。
这个问题,当时学递归的时候,我记得做过。但是已经一年半没写过递归和动态规划。所以,第一反应是用数学思路解决。
数学的想法是这样的:
n已知
我们创建一个列表存放执行的步骤:
比如,有三个台阶。
**[1,1,1]**代表,我们每次走一个台阶,完成这个任务。
**[1,2]**代表,先走1个台阶,再走2个台阶。完成任务。
**[2,1]**代表,先走2个台阶,再走1个台阶。完成任务。
当已知的台阶数为n, 自然就有下面的想法。
- [ n个1 ] 意为走了n个1完成任务
- [ n-1 个 1; 1 个 2 ] 意为走了n-1个1, 走了一个2完成任务。
- [ n-2 个 1; 2 个 2 ] 意为走了n-2个1, 走了两个2完成任务。
…
一个重要的点是:
当我们采用走了n-1个1,和一个2时,它的方法总数其实应该是:
意为: 将1个2放到n-1个1中。
所以最后的结果应该为:
所有的和为:
sum = 1 + Cnk(n-1, 1) + Cnk(n-2, 2) + … Cnk(n/2 , n/2) 偶数情况。
sum = 1 + Cnk(n-1, 1) + Cnk(n-2, 2) + … Cnk(n//2 + 1 , n//2 - 1) 奇数情况。
注: n//2 为: 用n整除2, 然后取得的数向下取整。 (2.1取2, 2.9取2)
代码如下:
def computer(n):
all_ways = 1
if n % 2 == 0:
stop_num = int(n / 2)
for i in range(1, stop_num + 1):
all_ways += Cnk(n - i, i)
if n % 2 == 1:
stop_num = (n // 2) + 1
for i in range(1, stop_num + 1):
all_ways += Cnk(n - i, i)
return all_ways
def Cnk(n, k):
value1 = 1
for i in range(k):
value1 = value1 * (n - i)
value2 = 1
for i in range(1, k + 1):
value2 = value2 * i
ans = value1 / value2
return ans
def main():
n = 6
ways = computer(n)
print(ways)
main()
因为当时只给了15min写代码,所以没有写出来。是我比较菜。这是我面试完之后花了30min左右补全的结果。
纪念人生第一次面试就凉凉的腾讯面试。