剑指Offer(Java实现):斐波那契数列 + 旋转数组中的最小数字

package com.dengzm.jianzhioffer;

/**
 * @Description 010 斐波那契数列
 * Created by deng on 2018/12/19.
 */
public class Jianzhi010 {

    public static void main(String[] args) {
        long q1 = fibonacci(100);
        System.out.println(q1);
    }

    //题目1:求斐波那契数列的第n项
    //使用递归会有很多重复计算,而且当n特别大时,递归可能会造成调用栈溢出
    //使用for循环计算:避免了重复计算
    //
    //题目2:青蛙跳台阶问题
    //一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶共有多少种跳法
    //f(n) = f(n-1) + f(n-2)
    public static long fibonacci(long n) {
        if (n <= 0)
            return 0;

        if (n == 1 || n == 2)
            return 1;

        long firstNum = 1;
        long secondNum = 1;
        long result = 0;

        for (int i = 3; i <= n; i ++) {
            result = firstNum + secondNum;
            firstNum = secondNum;
            secondNum = result;
        }

        return result;
    }
}

package com.dengzm.jianzhioffer;

/**
 * @Description 011 旋转数组的最小数字
 * 把一个数组最开始的若干元素搬到数组的末尾,我们称之为数组的旋转。
 * 输入一个递增的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3,4,5,1,2}是{1,2,3,4,5}的一个旋转,该数组的最小值为1
 * Created by deng on 2018/12/19.
 */
public class Jianzhi011 {

    public static void main(String[] args) {
        //int[] nums = new int[] {3,4,5,1,2};
        //int[] nums = new int[] {1,2,3,4,5};
        int[] nums = new int[] {1,1,0,1,1};
        int result = findMinNum(nums);
        System.out.println(result);
    }

    //判空
    //因为旋转数组本身是两段有序的数组组合而成,可以使用类似二分法的方式。
    //找到中间值比较与左端的大小:如果大于左端,则middle为start;若小于,则middle为end
    //特殊情况:1.数组本身没有旋转,自身就是自己的旋转数组,故开始时增加判断
    //         2.{1,1,0,1,1,1},顺序遍历寻找最小值
    public static int findMinNum(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }

        if (nums[0] < nums[nums.length - 1]) {
            return nums[0];
        }

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

        return findMinNumCore(nums, 0, nums.length - 1);
    }

    private static int findMinNumCore(int[] nums, int start, int end) {
        if (end - start == 1 || start ==end) {
            return nums[end];
        }

        int middle = ((end - start) >> 1) + start;
        if (nums[middle] >= nums[start]) {
            return findMinNumCore(nums, middle, end);
        } else {
            return findMinNumCore(nums, start, middle);
        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值