斐波拉契序列几种实现

今天遇到一个面试题:输入n,如果n<=1,f(n)=1,其他f(n)=f(n-1)+f(n-2), 打印f(n)从1到n的值。

public class Fibonacci {

    private int n;
    private StringBuilder sb;
    private String format;

    @Before
    public void init() {
        n = 10;
        sb = new StringBuilder(n);
        format = "f(%s) = ";
    }

直接用递归的方式实现:

/**
     * 递归实现
     */
    @Test
    public void recursion() {
        for (int i = 1; i <= n; i++) {
            sb.delete(0, n);
            sb.append(String.format(format, i));
            sb.append(recursion(i));
            System.out.println(sb.toString());
        }
    }

    private int recursion(int n) {
        if (n <= 1) {
            return 1;
        } else {
            return recursion(n - 1) + recursion(n - 2);
        }
    }

测试结果如下:

面试官说用循环,循环实现:

/**
     * for循环实现
     */
    @Test
    public void fori() {
        if (n <= 1) {
            System.out.println(1);
        }
        int j = 1, k = 1;
        int sum;
        for (int i = 2; i <= n; i++) {
            // f(n)=f(n-1)+f(n-2)
            // 把j作为f(n-1),k作为f(n-2)
            sum = j + k;
            k = j;
            j = sum;

            sb.delete(0, n);
            sb.append(String.format(format, i));
            sb.append(sum);
            System.out.println(sb.toString());
        }
    }

测试结果如下:

他说代码可以更加精简、高效,再次修改:

/**
     * for循环更高效实现
     */
    @Test
    public void forEfficient() {
        if (n <= 1) {
            System.out.println(1);
        }
        int temp = 1;
        int sum = 1;
        for (int i = 2; i <= n; i++) {
            // f(n)=f(n-1)+f(n-2)
            // 此时把sum作为f(n-1),temp作为f(n-2)
            sum = sum + temp;
            // 计算后sum就是f(n)
            // temp = f(n-1) = f(n) - f(n-2)
            temp = sum - temp;

            sb.delete(0, n);
            sb.append(String.format(format, i));
            sb.append(sum);
            System.out.println(sb.toString());
        }
    }

测试结果如下:

后面几面的编程题相关问题:

给一个无序数组,找出第K个大的数

比如23, 5, 7, 2,第2大的数就是7;

快速排序partition函数,比如10个数,找第5大的数,进行降序排列,在一次快排后,返回的下标假如为2就是这个数最终的位置,并且这个左边的所有的数都比它大,右边的所有数都比他小,然后就找3-9的数进行partition……

如果有有序数组相关的问题,应该要想到二分查找,根据数组下标二分!

很多编程题,校招时感觉简单,社招需要想一想才能做出来。

原文地址:https://www.cnblogs.com/theRhyme/p/11755154.html

时间: 2024-11-02 12:03:44

斐波拉契序列几种实现的相关文章

数据结构(六)查找---有序表查找(三种查找方式:折半,插值,斐波拉契查找)

前提 有序表查找要求我们的数据是有序的,是排序好的,我们只需要进行查找即可 我们下面将介绍折半查找(二分查找),插值查找,斐波那契查找 一:折半查找 (一)定义 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. (二)查找过程 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关

c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)

写一个函数,输入n,求斐波拉契数列的第n项. 斐波拉契数列:1,1,2,3,5,8...,当n大于等于3时,后一项为前面两项之和. 解:方法1:从斐波拉契数列的函数定义角度编程 #include<stdio.h> int fibonacci(int n) { int num1=1, num2=1, num3=0,i; if (n <= 2) { printf("斐波拉契数列的第%d项为:%d\n",n,num1); } else { for (i = 2; i <

青蛙跳台阶问题-斐波拉契数列

题目1:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级.求总共有多少种跳法 首先我们考虑最简单的情况,加入只有1级台阶,那显然只有一种跳法,如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级:另外一种就是一次跳2级 现在我们来讨论一般情况.我们把n级台阶时的跳法看成是n的函数,记为f(n).当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1):另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的

斐波拉契数列的计算方法

面试题9.斐波拉契数列 题目: 输入整数n,求斐波拉契数列第n个数. 思路: 一.递归式算法: 利用f(n) = f(n-1) + f(n-2)的特性来进行递归,代码如下: 代码: long long Fib(unsigned int n) { if(n<=0) return 0; if(n==1) return 1; return Fib(n-1) + Fib(n-2); } 缺陷: 当n比较大时递归非常慢,因为递归过程中存在很多重复计算. 二.改进思路: 应该采用非递归算法,保存之前的计算结

斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - 1) + F(n - 2),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n).第一个斐波拉契数为F(0) = 1. 给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod 1000000007. 斐波拉契数列的计算是一个非常经典的问题,对于小规模的n,很容易用递归的方式来获取,对于稍微大一点的n,为

斐波拉契数列应用

斐波拉契数列的应用实例 什么是斐波拉契数列(Fibonacci sequence)?将其前几项写出来就是:0 1 1 2 3 5 8 13 21....... 观察不难发现其规律是,从第二项起,每一项的值都为前两项的和.而且这个数列有趣的地方就在于这个非常特殊的规律.它是有通项公式的,但是推导与主题无关,而且也几乎用不上,所以就不多叙述. long fi(int n) { if(n==1||n==2) return 1; else return fi(n-1)+fi(n-2); } 但是如果这样

斐波拉契数列的递归、非递归、公式法多种方法实现

实现斐波拉契数列:1,1,2,3,5,8...,当n>=3时,f(n)=f(n-1)+f(n-2). 解:求解斐波拉契数列方法很多,这里提供了4种实现方法和代码,由于第5种数学公式方法代码太过繁琐,只做简单介绍 方法一:递归调用,每次递归的时候有大量重复计算,效率低,可将其调用的过程转化成一颗二叉树进行分析,二叉树的总结点个数不超过(2^n-1)个,由于其是不完全二叉树,那么函数计算的次数必小于(2^n-1),时间复杂度为O(2^n):递归调用的深度为n,空间复杂度为O(n) 方法二:非递归数组

斐波那契序列与跳台阶

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25337983 剑指offer上的第就题,简单题,在九度OJ上测试通过. 主要注意以下几点: 1.用非递归实现,递归会超时 2.结果要用long long保存,不然会发生结果的溢出,从而得到负值 3.如果是在VC++6.0下编译的,long long是illegal的,要用_int64代替,同时输出的转化以字符也要用%64d代替%lld 时间限制:1 秒 内存限制:32 兆 题目描述: 大

剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调用的层级太多,就会超出栈容量. 循环:通过设置计算的初始值及终止条件,在一个范围内重复运算. 斐波拉契数列 题目一:写一个函数,输入n,求斐波拉契(Fibonacci)数列的第n项,定义如下: 第一种解法:用递归的算法: long long Fabonacci(unsigned int n) { i