Climbing Stairs
题目大意是指,用1,2排列,使其和为n,有多少种排法。
基本思路
大概就是对不同数量的1,挑选1的位置。
挑选的话,就需要求组合数,
求组合数,就需要阶乘?!
阶乘就会特别慢,
基本方案
class Solution(object):
def pmt(self, a, all):
# 阶乘
f = lambda x: x and x * f(x - 1) or 1
return f(all)/ (f(a) * f(all - a))
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
num_2, num_1 = n / 2, n % 2
ways = 1
for i in xrange(num_2):
num_21 = num_1 + i * 2
num_22 = num_2 - i
ways += self.pmt(num_21, num_21 + num_22)
return ways
还没看到结果, 反正是慢成狗了。
学习到了阶乘的简短写法
x and 的写法是为了保证输入为0的时候的返回值。
改进方案
先写公式:
Σnum_2i=0Combination(i,i∗2+num_1+num_2−i)=Σnum_2i=0Combination(i,i+num_1+num_2)=Σnum_2i=0(i+num_1+num_2)!i!∗(num_1+num_2)!
显然这个公式是可以化简的:
Σnum_2i=0(i+num_1+num_2)!i!∗(num_1+num_2)!=Σnum_2i=0(i+num_1+num_2)!i!(num_1+num_2)!
假设有: K=num_1+num_2
那么:
上式=1K!Σnum_2i=0(K)(K+1)...(K+i)
考虑到这个式子比较方便写程序了。
class Solution(object):
def climbStairs(self, n):
if n == 0:
return 1
num_1, num_2 = n % 2, n / 2
k = num_1 + num_2
f = lambda x: x and x * f(x - 1) or 1
v = lambda x, i:(i+1) and v(x, i-1) * (x + i) or 1
ways = sum(map(lambda s: v(k, s), range(num_2))) / f(k)
return ways
写完之后,发现确实快很多,
不过结果不对, 显然上面有一步推错了(Orz)。
明天再改吧。。。要睡觉了