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

题目链接

https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。  

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

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

解题思路

方式一:暴力枚举

初始化变量ans为INT_MAX,for循环扫描一遍输入的数组并迭代更行ans的值(当数组中元素的值小于ans,则更新ans的值),时间复杂度O(n)

方式二:双指针

该数组有个特性,可以看成是由一个有序序列拆分成俩个部分的有序数列,所以比较连续两个元素的大小即可。

方式三:二分查找

普通的二分查找算法都是在有序数组中寻找是否出现每个值,在本题中,数组不在完全有序且题目并没有给我们一个需要寻找的值。

题目提供的数组部分有序,且我们只需要比较numbers[mid]、numbers[l]、numbers[r]这三个元素的大小即可,所以我们依旧可以使用二分查找算法,把时间复杂度从O(n)将为O(logn)

伪代码如下:

 

 为什么更新r值的时候不需要+1,而l值需要呢?

题目要找的是最小值,所以当numbers[mid] < numbers[l]的时候,numbers[mid]很可能是我们所要寻找的答案,而当numbers[mid] > numbers[r],因为numbers[r]的值已经小于numbers[mid],所以numbers[mid]不可能是我们要找的答案,所以需要更新l的值为mid + 1。

如果出现numbers[mid] == numbers[l] == numbers[r] == value的时候该怎么办?例如numbers = [3,3,1,3]、numbers = [1, 1, 1, 2, 3, 1]

无论value值是否是我们所需要的最小值,我们都可以把它删除,因为一共有3个value值,删除最右边的一个value元素不会造成影响。

AC代码

暴力枚举

class Solution {
    public int minArray(int[] numbers) {
        // 暴力枚举
        int ans = 123456789;
        for(int i = 0; i < numbers.length; i++)
        {
            if(numbers[i] < ans) ans = numbers[i];
        }
        return ans;
    }
}

双指针

class Solution {
    public int minArray(int[] numbers) {       
        //双指针
        int l = 0;
        int r = numbers.length - 1;
        while(l < r){
            if(numbers[l] > numbers[l+1]) return numbers[l+1];
            if(numbers[r] < numbers[r-1]) return numbers[r];
            l++;
            r--;
        }
        return numbers[0];
    }
}

二分查找

class Solution {
    public int minArray(int[] numbers) {       
        //二分
        int l = 0;
        int r = numbers.length - 1;
        while(l <= r)
        {
            int mid = (l + r) / 2;
            if(numbers[mid] < numbers[l]){
                r = mid;
            }else if(numbers[mid] > numbers[r]){
                l = mid + 1;
            }else if(numbers[mid] == numbers[r]){
                r--;
            }else{ //代表数组已经是一个完全有序的数组
                break;
            }
        }
        return numbers[l];
    }
}

 

posted @ 2020-07-22 16:42  控球强迫症  阅读(163)  评论(0编辑  收藏  举报