剑指 Offer 11. 旋转数组的最小数字

❤️‍来自专栏《LeetCode基础算法题》 欢迎订阅❤️‍

@[TOC]

关于作者

  • 作者介绍

🍓 博客主页:作者主页
🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。
🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

1、题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2][1,2,3,4,5] 的一次旋转,该数组的最小值为1。

实例1

输入: [3,4,5,1,2]

输出: 1

实例2

输入: [2,2,2,0,1]

输出: 0

注意

2、思路🧠

方法一:暴力解法

  1. 根据题意,第一时间想到通过暴破来解决,用变量记录当前遍历过程中遇到的最小值,在遍历结束后,返回最小值即可。
  2. 为什么说暴力不优雅呢,因为我们知道数组被旋转,在遍历过程中,只要有数字小于 numbers[0],那么该数字一定是最小值。

方法二:二分优化

暴力不是我们的解题目标,暴力是进不了大厂的,所以小伙伴们在做题的时候还是要想一想优化的解法熬。

  1. 创建两个指针 L, R 分别指向 numbers 头和尾,计算出两指针之间的中间索引值 M,会出现以下三种情况:
  2. 我们分别考虑
    • M > R 时,最小值一定在 M 右侧,所以将 L 移动到 M + 1 的位置。
    • M < R 时,最小值一定在 M 左侧也就是 M 的位置,所以将 R 移动到 M 的位置。
    • M 既不大于 L 指针的值,也不小于 R 指针的值,意味着 M 可能等于 L 指针的值,或 R 指针的值,这时候唯一能继续进行程序的办法就是让 R 指针递减,来找最小值。

废话少说~上代码!

3、代码

第一次commit AC

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

时间复杂度:O(n)

空间复杂度:O(1)

第二次commit AC

class Solution {
    public int minArray(int[] numbers) {
        int L = 0,R = numbers.length - 1;
        while(L < R){
            int M = L + ((R - L) >> 1);//这里是向下取整
            if(numbers[M] > numbers[R]) {
                L = M + 1;
            }
            else if(numbers[M] < numbers[R]) {
                R = M;
            }
            else R -= 1;
        }
        return numbers[L];
    }
}

时间复杂度:O(log n)
空间复杂度:O(1)

image-20220313161502159

4、总结

该题目的使用二分查找的应用实例,首先要对二分法有所了解。

二分法模板:

public static int binarysearch(int arr[], int L, int R, int target){
    int count = 0;
    int M = (L + R) >> 1;
    if(L > R) return -1;

    if (target > arr[M]){
        return binarysearch(arr, M + 1, R, target);
    }else if(target < arr[M]){
        return binarysearch(arr, L, M - 1, target);
    }else {
        return M;
    }
}

原题链接:剑指 Offer 11. 旋转数组的最小数字