每日一题——旋转数组的最小数字

题目


有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤n≤10000,数组中任意元素的值: 0≤val≤10000

要求:空间复杂度:O(1) ,时间复杂度:O(logn)

示例1

输入:
[3,4,5,1,2]
返回值:
1

示例2

输入:
[3,100,200,3]
返回值:
3

思路


二分法:

  • mid = (start + end) / 2 为二分的中间位置。
  • mid,start,right分为三种情况:
    • nums[mid] > nums[end]时, 那么最小值一定在 [mid+1,end]区间中;
    • nums[mid] = nums[end]时,无法判断最小值在哪个区间,所以此时只能缩小end的值;
    • nums[mid] < nums[end]时,那么最小值一定在[start,mid]区间内。

解答代码


class Solution {
public:
    /**
     * @param nums int整型vector 
     * @return int整型
     */
    int minNumberInRotateArray(vector<int>& nums) {
        // write code here
        int start = 0;
        int end = nums.size() - 1;
        while (start != end) {
            int mid = (start + end) / 2;
            if (nums[mid] > nums[end]) {
                //最小的数字在mid右边
                start = mid + 1;
            } else if (nums[mid] == nums[end]) {
                //无法判断,一个一个试
                end = end - 1;
            } else if (nums[mid] < nums[end]) {
                //最小数字要么是mid要么在mid左边
                end = mid;
            }
        }
        return nums[end];
    }
};