(原)剑指offer之旋转数组
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,
该数组的最小值为1。
设数组为rotateArray
方法1:逐个遍历算法复杂度O(n)
方法2:二分查找
很明显不能单纯的二分查找,
情况一:数组旋转0位
由于是递增数列直接return 数组首元素即可,
情景二:旋转n位这时我们把数组划分为两个有序的子数组,前面子数组元素都大于后面的子数组元素,
我们用三个迭代器来实现二分查找,low指向前面大数组,heigh指向后面小数组,mid指向中间元素,很明显如果*mid>*low,mid指向的元素就位于"大数组中",否则则指向小数组
前者我们令low = mid,后者我们令heigh = mid重新确定查找区间。
情景三:当第一次判断如果 *low = *mid = *heigh则只能采用顺序查找了因为我们无法确定数组是旋转后的数组,还是有序数组
下面是c++代码实现
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray){ int len = rotateArray.size(); if( len < 1){ return 0; } int low = 0; int high = len - 1; while(low < high){ int mid = (low + high)/2; if(rotateArray[low] < rotateArray[high]){ return rotateArray[low]; } if(high - low == 1){ return rotateArray[high]; } if(rotateArray[mid] == rotateArray[low] && rotateArray[mid] == rotateArray[high]){ int min = rotateArray[low]; for(int i = low; i <= high; ++i){ if(min > rotateArray[i]){ min = rotateArray[i]; } } return min; } if(rotateArray[mid] >= rotateArray[low]){ low = mid; } else if(rotateArray[mid] <= rotateArray[high]){ high = mid; } } } };