您的位置:首页 > 大数据 > 人工智能

LeetCode: 013-Climbing Stairs

2016-01-08 00:46 260 查看

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)!\Sigma_{i=0}^{num\_2} Combination(i, i * 2 + num\_1 + num\_2 - i) = \Sigma_{i=0}^{num\_2} Combination(i, i + num\_1 + num\_2)
= \Sigma_{i=0}^{num\_2}\frac{ (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)!\Sigma_{i=0}^{num\_2}\frac{(i + num\_1 + num\_2)!}{ i! * (num\_1+num\_2)!}
=\frac{\Sigma_{i=0}^{num\_2}\frac{(i+num\_1 + num\_2)!}{i!}}{(num\_1 + num\_2)!}

假设有:K=num_1+num_2K=num\_1 + num\_2

那么:

上式=1K!Σnum_2i=0(K)(K+1)...(K+i)上式 =\frac{1}{K!} \Sigma_{i=0}^{num\_2}(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)。

明天再改吧。。。要睡觉了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: