【论算法的重要性】:一列数的规则如下:1 1 2 3 5……,递归实现第30位数是多少?

【题目】:一列数的规则如下:1 1 2 3 5……,递归实现第30位数是多少?

百度搜了几十个结果,无一例外是这代码,结果是832040:

static Int64 GetNumber(int pos)
{
    if (pos <= 2)
        return 1;
    return GetNumber(pos - 1) + GetNumber(pos - 2);
}

错? 答案没错!而且结果秒出。

但如果改为求第60位数时,你将会发现性能的极大问题:居然2个小时还没出结果(具体未知),我们用稿纸人工计算早都出结果了。用稿纸人工计算的做法,求第31位只是比第30位多做1次加法就行,第60位只是比第30位多做30次加法就行。

但这函数,求第N位的时间=求第N-1位的时间+求第N-2位的时间,假如求第31位的时间和求第32位的时间都是1秒,那么从第31位往后的耗时分别是:1秒 1秒 2秒 3秒 5秒 8秒 13秒......。这个数字,居然跟题目的数字串一样,实在是太有意思了。那么第60位的耗时就是832040秒(约9.6天),My god.

以下是修正做法,通过增加1个数组来保存每1位的结果,实现每增加1位也只是增加1次加法,求第60位结果也秒出(即使是求第100位结果也秒出):

static void Main(string[] args)
{
    int pos = 60;
    Console.WriteLine(GetNumber(pos, new Int64[pos]));
    Console.ReadLine();
}
static Int64 GetNumber(int pos, Int64[] nums)
{
    if (pos <= 2)
        return 1;
    if (nums[pos - 3] == 0)
        nums[pos - 3] = GetNumber(pos - 2, nums);
    if (nums[pos - 2] == 0)
        nums[pos - 2] = GetNumber(pos - 1, nums);
    return nums[pos - 3] + nums[pos - 2];
}

这就是算法的重要性!

一个简单的思路,性能随时超万倍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值