《剑指Offer》读书笔记06:旋转数组的最小数字

来源:互联网 发布:网络四大名著三大奇书 编辑:程序博客网 时间:2024/06/05 07:39

题目描述

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


解题思路

  1. 简单直接粗暴方法:从头至尾遍历数组,找出最小元素,时间复杂度O(n).
  2. 排序数组中可以用二分查找法(时间复杂度O(log n)),此旋转数组基本有序。
  3. 用left和right指向数组第一个和最后一个元素。按旋转数组规则,第一个元素应该大于或者等于最后一个元素。找到中间元素middle。若middle元素大于等于left元素,前半部分递增,最小元素在后半部分,将left移至middle位置;若middle元素小于等于right元素,后半部分递增,最小元素在前半部分,将right移至middle位置。 这样就能缩小一半的范围,然后重新做新一轮查找。
  4. 最后left指向前面子数组的最后一个元素,right指向后面子数组的第一个元素,两者相邻,right所指元素为最小元素,循环结束。
  5. 特殊情形一,原数组的旋转了0个或n个元素,旋转数组与原数组相同,此时最小元素在最前面。
  6. 特殊情形二,当left,right和middle均相同时,无法判断middle元素位于前半部分还是后半部分。如原数组{0,1,1,1,1,1},其旋转数组{1,0,1,1,1,1}和{1,1,1,1,0,1}无法判断。此时需要暴力顺序查找。

参考代码

class Solution {public:    int minNumberInRotateArray(vector<int> rotateArray) {        if ( rotateArray.empty() ) {            //throw new std::exception("Invalid parameters!");            return 0;        }        int left = 0;        int right = rotateArray.size()-1;        int middle = left;//应对特殊情形一,left所指小于right所指,跳过while循环。        while (rotateArray[left] >= rotateArray[right] ) {            if ( right - left == 1 )  {                middle = right;                break;            }            middle = (right+left)/2;            if ( rotateArray[middle] == rotateArray[left] //特殊情形二                && rotateArray[middle] == rotateArray[right] ) {                return minNumberInOrderArray(rotateArray, left, right);            }            if ( rotateArray[middle] >= rotateArray[left] ) {                left = middle;            } else if ( rotateArray[middle] <= rotateArray[right] ) {                right = middle;            }        }        return rotateArray[middle];    }    //顺序查找    int minNumberInOrderArray(vector<int> rotateArray, int left, int right) {        int minNumber = rotateArray[left];        for ( int i = left+1; i <= right; i++ ) {            if ( minNumber > rotateArray[i] ) {                minNumber = rotateArray[i];            }        }        return minNumber;    }};
0 0
原创粉丝点击