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

题目:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

例子:

如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

链接:

剑指Offer(第2版):P82

LeetCode-153:Find Minimum in Rotated Sorted Array

思路标签:

算法:二分查找

解答:

1. C++

  • 首先能想到的就是顺序遍历,数组中最小的元素即为整个旋转数组的最小元素,但算法时间复杂度为O(n);
  • 由旋转数组的特性,因为经排序好的数组旋转得到的,所以由其特性可以知道,除了不旋转的情况(即原数组),旋转数组可以划分为两个排序的子数组,前面的子数组元素均大于后面的子数组元素,存在分界线,所以可以想到的就是利用二分查找法,实现时间复杂度为O(logn);
  • 注意考虑以下几种情况的处理:
  • 1)数组元素为空的情况,(判断,直接返回0);
  • 2)数组元素只有一个的情况,(判断,直接返回该元素);
  • 3)数组旋转0个元素,也就是没有旋转的情况,(最后返回mid对应的值,所以初始时令mid=low,遇到该情况while条件不成立,依然返回mid对应的值);
  • 4)如,排序数组为{0,1,1,1,1},旋转数组为{1,0,1,1,1}或者{1,1,1,0,1},当为这两种情况时,mid=low=high,无法确定最小的元素在左还是在右,所以这个时候就需要采用顺序查找的方式。
class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size() == 0) return 0;
        if(rotateArray.size() == 1) return rotateArray[0];

        int low = 0;
        int high = rotateArray.size()-1;
        int mid = low;
        while(rotateArray[low] >= rotateArray[high]){
            // 结束条件
            if(high - low == 1){
                mid = high;
                break;
            }

            mid = (low + high)/2;

            //顺序查找
            if(rotateArray[low] == rotateArray[high] && rotateArray[low] == rotateArray[mid])
                return minInOrder(rotateArray, low, high);

            if(rotateArray[mid] >= rotateArray[low])
                low = mid;
            else if(rotateArray[mid] <= rotateArray[high])
                high = mid;
        }

        return rotateArray[mid];
    }

    int minInOrder(vector<int>& numbers, int low, int high){
        int result = numbers[low];
        for(int i = low+1; i<=high; ++i){
            if(result > numbers[i])
                result = numbers[i];
        }

        return result;
    }
};

2. Java

  • 考虑的情况较少。

http://blog.csdn.net/koala_tree/article/details/78477304

你可能感兴趣的:(剑指Offer,剑指Offer,笔试面试,编程题)