斐波那契数列,青蛙跳台阶问题,旋转数组的最小数字

一.斐波那契数列

写入一个函数,输入一个数字n,求斐波那契数列的第n项,该数列的定义如下:
F(0)=0,F(1)=1
F(N)=F(N-1)+F(N+2),其中N>1
斐波那契数列由0和1开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需取模1e9+7

解决方案:
1.递归法(分治)
原理:把F(N)问题的计算拆分成F(N-1)+F(N-2)子问题的计算递归,并以F(0)和F(1)为终止条件

public int fib(int n){
  if(n==0) return 0;
  if(n==1) return 1;
 
 return (fib(n-1)+fib(n-2))%1000000007;
}

这种解法从逻辑上没问题,但随着n的增大其时间复杂度O(2^n)会很大。

2.通过题目我们可以想到第二种方法:
设正整数x,y,p 求余符号位%,则有:(x+y)%p=(x%p+y%p)%p
所以有:
F(n)%p=[f(n-1)%p+f(n-2)%p]%p

public int fib(int n){
 int a=0;
 int b=1;
 int sum;
 for(int i=0;i<n;i++){
   sum=(a+b)%1000000007;
   a=b;
   b=sum;
 }
 return a;
}

这个解法的时间复杂度仅为O(n).

3.思路简单清晰解法
当n<=2时特殊处理,然后到n=3开始进行计算,保持one和two总是要计算位置的前两位数值从而得到结果。

class Solution {
    public int fib(int n) {
        int end=0;
        if(n<=1){ 
            end=n;
        }else if(n==2){
            return 1;
        }else{
            int one=1;
            int two=1;
            int cache=0;
            for(int i=2;i<n;i++){
               end=one+two;
               end%=1000000007;
               cache=one;
               one=end;
               two=cache;
            }
        }
      return end;
    }
}

二.青蛙跳台阶问题

一只青蛙一次可以调上1级台阶,也可以跳上两级台阶,求该青蛙跳上一个n级台阶总过有多少种跳法。

解法:我们可以分析此问题发现其实也是一个斐波那契数列问题

int test(int n){
int a=1,b=1,sum=0;
 for(int i=0;i<n;i++){
  sum=a+b;
  a=b;
  b=sum;
  }
 return a; 
}

三.旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转,输入一个递增排序的数组的一个旋转,输出旋转组的最小元素。

解法:
1.找第一个小于前者的数并返回,特殊情况:只有一个元素,输出,都是排序排列的,输出第一个元素

  public int minArray(int[] numbers) {
        int end=numbers[0];
        for(int i=0;i<numbers.length-1;i++){
            if(numbers[i]>numbers[i+1]){
                end=numbers[i+1];
            }
        }
        return end;
    }

时间复杂度为N,空间为1
2.二分查找法:本题的本质其实就是找数组中的最小元素,我们可以用二分查找来查找

public int minArray(int[] numbers){
 int i=0,j=numbers.length-1;
 
 while(i<j){
   int m=(i+j)/2;
   if(numbers[m]>numbers[j])  i=m+1;
   else if(numbers[m]<numbers[j])  j=m;
   else j--;
 }
 
 return numbers[i];
}

此方法的时间复杂度位Log2N,空间复杂度为1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值