题解 | #JZ7斐波那契数列#

斐波那契数列

http://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3

同样的类型的题还有兔子繁殖的问题。
此题可以用丰富的解法来解答。
考察知识:[递归],[记忆化搜索],[动态规划], [递推]。
难度:一星

1 分治

分治思想简述
当一个问题规模较大且不易求解的时候,就可以考虑将问题分成几个小的模块,再逐一解决;
分治思想一般都会和递归一起使用,因为采用分治思想处理问题,其各个小模块通常具有与大问题相同的结构,这种特性也使递归技术有了用武之地。

所以,分治是一种思想,递归是一种技术!

1.1 分治 | 递归

大量重复计算,超时!

迭代 和 递归

对比两种实现方式,迭代和递归的区别是:迭代使用的是循环结构,递归使用的是选择结构;

使用递归能使程序的结构更清晰、更简洁、更容易让人理解,从而减少读懂代码的时间;

但是大量的递归调用会创建函数的副本,会消耗大量的时间和内存,而迭代则不需要;

递归函数分为调用和回退阶段,递归的回退顺序是它调用顺序的逆序。

public class Solution {
    public int Fibonacci(int n) {
        if(n<=1)  return n;
        return Fibonacci(n-1) + Fibonacci(n-2);
    }
}

1.2递归优化:记忆化搜索

用成员变量数组装着算过的数。 依旧反复递归调用自己,但用一个 if 判断来截断运算!!

public class Solution {
    int ans[] = new int[40];
    public int Fibonacci(int n) {
        if(n<=1)  return n;
        if (ans[n]!=0) return ans[n];// 减少递归次数的关键。
        return ans[n]= Fibonacci(n-1) + Fibonacci(n-2);
    }
}

2 动态规划

动态规划类似分治,同样是将原问题分解成子问题,通过求解子问题而得到原问题的解。但不同的是,动态规划是自底向上分解,并且会保存子问题的解,在需要时可直接拿过来使用,这一点是区别于分治的。

int Fibonacci(int n) {
     int ans[] = new int[40];
        ans[1]=1;
        for (int i=2; i<=n; ++i) {
            ans[i] = ans[i-1] + ans[i-2];
        }
        return ans[n];
}

2.1 动态规划优化:递推

我比较擅长这个。

public class Solution {
    public int Fibonacci(int n) {
        if(n == 0)  return 0;
        }else if(n == 1) return 1;
        int sum = 0;
        int two = 0;
        int one = 1;
        for(int i=2;i<=n;i++){
            sum = two + one;
            two = one;
            one = sum;
        }
        return sum;
    }
}

2.2递推: 还可以优化,用更少的变量

这个一定要学习到。 用两个指针就可以完成遍历。

public class Solution {
    public int Fibonacci(int n) {
        if(n == 0)  return 0; 
        if(n == 1)  return 1; 
        int sum = 1;
        int one = 0;
        for(int i=2;i<=n;i++){ //找规律找出来的精华。
            sum = sum + one;
            one = sum - one;
        }
        return sum;
    }
}
全部评论

相关推荐

头像
10-13 18:10
已编辑
东南大学 C++
。收拾收拾心情下一家吧————————————————10.12更新上面不知道怎么的,每次在手机上编辑都会只有最后一行才会显示。原本不想写凉经的,太伤感情了,但过了一天想了想,凉经的拿起来好好整理,就像象棋一样,你进步最快的时候不是你赢棋的时候,而是在输棋的时候。那废话不多说,就做个复盘吧。一面:1,经典自我介绍2,项目盘问,没啥好说的,感觉问的不是很多3,八股问的比较奇怪,他会深挖性地问一些,比如,我知道MMU,那你知不知道QMMU(记得是这个,总之就是MMU前面加一个字母)4,知不知道slab内存分配器-&gt;这个我清楚5,知不知道排序算法,排序算法一般怎么用6,写一道力扣的,最长回文子串反问:1,工作内容2,工作强度3,关于友商的问题-&gt;后面这个问题问HR去了,和中兴有关,数通这个行业和友商相关的不要提,这个行业和别的行业不同,别的行业干同一行的都是竞争关系,数通这个行业的不同企业的关系比较微妙。特别细节的问题我确实不知道,但一面没挂我。接下来是我被挂的二面,先说说我挂在哪里,技术性问题我应该没啥问题,主要是一些解决问题思路上的回答,一方面是这方面我准备的不多,另一方面是这个面试写的是“专业面试二面”,但是感觉问的问题都是一些主管面/综合面才会问的问题,就是不问技术问方法论。我以前形成的思维定式就是专业面会就是会,不会就直说不会,但事实上如果问到方法论性质的问题的话得扯一下皮,不能按照上面这个模式。刚到位置上就看到面试官叹了一口气,有一些不详的预感。我是下午1点45左右面的。1,经典自我介绍2,你是怎么完成这个项目的,分成几个步骤。我大致说了一下。你有没有觉得你的步骤里面缺了一些什么,(这里已经在引导我往他想的那个方向走了),比如你一个人的能力永远是不够的,,,我们平时会有一些组内的会议来沟通我们的所思所想。。。。3,你在项目中遇到的最困难的地方在什么方面4,说一下你知道的TCP/IP协议网络模型中的网络层有关的协议......5,接着4问,你觉得现在的socket有什么样的缺点,有什么样的优化方向?6,中间手撕了一道很简单的快慢指针的问题。大概是在链表的倒数第N个位置插入一个节点。————————————————————————————————————10.13晚更新补充一下一面说的一些奇怪的概念:1,提到了RPC2,提到了fu(第四声)拷贝,我当时说我只知道零拷贝,知道mmap,然后他说mmap是其中的一种方式,然后他问我知不知道DPDK,我说不知道,他说这个是一个高性能的拷贝方式3,MMU这个前面加了一个什么字母我这里没记,别问我了4,后面还提到了LTU,VFIO,孩子真的不会。
走呀走:华子二面可能会有场景题的,是有些开放性的问题了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务