题意思路:

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

方法一:暴力枚举
通过遍历数组求出最小的元素

复杂度分析

时间复杂度:O(N),N数组的长度,遍历数组;

空间复杂度:O(1),未开辟新空间

代码:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int res=INT_MAX;

        for( auto i : rotateArray){
            res=min(res,i);
        }
        return res;

    }
};

方法二:二分法
可以将这个旋转的数组看作是前后两个有序的子数组, 设置指针mid = (l + r) / 2.

1.当选取的中间值 mid 所对应的值大于 l 所对应的值时,说明此时 mid 还在第一有序的数组中,而我们所要求解的最小值是在第二个有序数组的第一个位置,此时也就是在 mid 的后面,我们就将 l 移到 mid 所在的位置.

2.当 r 所对应的值大于 mid 所对应的值时,说明最小值可能是 mid 所对应的值或者在 mid 的前面,我们将 r移到 mid 所在的位置.

3.若r所对应的值等于mid所对应的值时,此时减少区间缩小范围。

最后 l 所在的位置就是最小值的位置,直接返回即可.

图解:
图片说明

复杂度分析

时间复杂度:O(logN),N数组的长度,二分遍历数组;

空间复杂度:O(1),未开辟新空间
代码:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if (rotateArray.size() == 0) return 0;
        int l = 0, r = rotateArray.size() - 1;
         while (l < r) { // 当左指针小于右指针满足条件
            if (rotateArray[l] < rotateArray[r]) { // 得到最小值
                return rotateArray[l];
            }
            int mid = l + r>> 1;//得到中间指针 比较大小
            if (rotateArray[mid] > rotateArray[r]) { // 
                l = mid + 1;
 //原始数组是非递减,所以可以确定答案为 [mid+1...r]区间,所以 l = mid + 1
            }
            else if (rotateArray[mid] < rotateArray[r]) { //情况2
                r = mid;
            }
//说明答案肯定不在[mid+1...r],但是arr[mid] 有可能是答案,所以答案在[l, mid]区间,所以r = mid;
            else { // 当rotateArray[mid] == rotateArray[r]时只能减少区间
                --r;
            }
        }
        return rotateArray[l];
    }
};