剑指offer刷题笔记之——旋转数组的最小数字

yangxiaodong 2019-01-14 PM 134℃ 0条

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

问题分析

旋转数组实际上可以划分为两个有序的子数组:前面的子数组的大小都大于后面子数组中的元素(或前面子数组最小值等于后面子数组的最大值)**。那么实际上最下元素就是两个子数组的分界线。本题目给出的数组一定程度上是有序的,因此使用二分查找法寻找这个最小的元素。

思路

  1. 使用两个指针,left,right分别指向数组的第一个元素和最后一个元素。按照题目的规定,第一个元素应该是大于最后一个元素的,如果第一个元素小于最后一个元素,则返回该元素
  2. 找到中间元素,如果中间元素大于第一个元素,则中间元素位于前面的递增子数组,此时最小元素位于中间元素后的子数组,另left指向中间元素后的一个元素,重复2
  3. 如果不满足2条件,如果中间元素,小于right,则后面子序列为有序,则最小值位于前面序列,另right指向mid元素。重复2
  4. 如果不满足2、3条件,则left指针顺序遍历,直到找到小于right指向值

代码

C++代码

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.empty())
            return 0;
        int left = 0, right = rotateArray.size() - 1;
        while(left < right)
        {
            if(rotateArray[left] < rotateArray[right])
                return rotateArray[left];
            int mid = left + (right - left) / 2;
            if(rotateArray[left] < rotateArray[mid])
            {
                left = mid + 1;
            }
            else if(rotateArray[mid] < rotateArray[right])
            {
                right = mid;
            }
            else
            {
                left++;
            }
        }
        return rotateArray[left];
    }
};
标签: none

非特殊说明,本博所有文章均为博主原创。

评论啦~