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

一.斐波那契数列

写入一个函数,输入一个数字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).

二.青蛙跳台阶问题

一只青蛙一次可以调上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){
    
    

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

}

时间复杂度为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

猜你喜欢

转载自blog.csdn.net/c1776167012/article/details/108672549