剑指Offer第六题:旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
采用二分法,比较的基准是索引为0的元素,
第一步:将尾部可能存在与array[0]相同的元素剔除
第二步:检查数组是否发生了旋转,若无,直接返回array[0]
第三步:二分搜索,当mid值小于array[0]时,mid位于右半部分(值比较小的区域)将right移动到mid,当mid值大于等于array[0]时,mid位于左半部分(值比较大的区域),将left移动到mid+1的位置(最后目标是让left指向最小值),
当left == right 时,left必然指向了最小的位置
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
//二分法
if(array == null || array.length == 0) return 0;
// 第一步将尾部可能存在的相等元素除外 3 4 5 6 1 2 3 3 3 3 变成 3 4 5 6 1 2
int r = array.length - 1;
while(array[r] == array[0]){
r -- ;
}
//第二步,如果没有发生旋转,此时最尾节点大于首节点
if(array[0] <= array[r]){
return array[0];
}
//第三步,二分搜索
int left = 0;
int right = r;
while(left < right){
int mid = left + (right - left)/2;
//当小于首部元素时,说明在后半部分,此时将右指针移动
if(array[mid] < array[0] ){
right = mid;
}
//否则在前半部分,将左指针移动
else{
left = mid + 1;
}
}
//最后的目标是将左指针移动到指向最小的值位置上
return array[left];
}
}