剑指offer——面8:旋转数组的最小数字 和 面9:斐波那契数列

本文探讨了寻找旋转数组最小值的有效算法,并通过改进解决了元素重复的问题。此外,还介绍了斐波那契数列的两种实现方法,一种为递归方式,另一种为循环方式,后者显著提升了计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length==0||array==null)
            return 0;
        int left=0,right=array.length-1;
        int mid=left;
        while(array[left]>=array[right]){
            if(right-left==1){
                mid=right;
                break;
            }
            mid=(right+left)/2;
            if(array[mid]>=array[left]){
                left=mid;
            }else if(array[mid]<=array[right]){
                right=mid;
            }
        }
        return array[mid];
    }
}
//运行时间:298ms占用内存:27872k

以上解法中,没有考虑元素重复的情况,比如{1,0,1,1,1}和{1,1,1,0,1}
则当两个指针与中间的元素一样时,无法判断中间的数字是在前面的子数组中还是在后面的子数组中,因此余姚用顺序查找的方法,修改代码如下:

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length==0||array==null)
            return 0;
        int left=0,right=array.length-1;
        int mid=left;
        while(array[left]>=array[right]){
            if(right-left==1){
                mid=right;
                break;
            }
            mid=(right+left)/2;
            if(array[left]==array[right]&&array[mid]==array[left])
                return MinOfOrder(array,left,right);
            if(array[mid]>=array[left]){
                left=mid;
            }else if(array[mid]<=array[right]){
                right=mid;
            }
        }
        return array[mid];
    }
    public int MinOfOrder(int[] array,int left,int right){
        int result=array[left];
        for(int i=left+1;i<=right;i++){
            if(result>array[i])
                result=array[i];
        }
        return result;
    }
}
//运行时间:328ms 占用内存:28080k

斐波那契数列

最常用的是递归,如下:

public class Solution {
    public int Fibonacci(int n) {
        if(n<=0)
            return 0;
        if(n==1)
            return 1;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }
}
//运行时间:1654ms占用内存:9264k

效率低下,修改递归为循环如下:

public class Solution {
    public int Fibonacci(int n) {
        int one=0,two=1;
        if(n<2)
            return n;
        int res=0;
        for(int i=2;i<=n;i++){
            res=one+two;
            one=two;
            two=res;
        }
        return res;
    }
}
//运行时间:23ms占用内存:9076k

提高了时间效率。也可以写为:

public class Solution {
    public int Fibonacci(int n) {
        if(n<2)
            return n;
        int[] res=new int[n+1];
        res[0]=0;
        res[1]=1;
        for(int i=2;i<=n;i++){
            res[i]=res[i-1]+res[i-2];
        }
        return res[n];
    }
}
//运行时间:26ms占用内存:9196k
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值