您的位置:首页 > 职场人生

剑指offer面试题8:旋转数组的最小数字

2019-08-09 17:38 786 查看

题目:把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{l ,2, 3, 4, 5}的一个旋转,该数组的最小值为1
思路:想利用旋转数组的局部有序性进行二分查找数组的最小值。
具体思路:
1、用两个指针分别指向数组的第一个元素和最后一个元素,根据题意,第一个元素应该是大于等于最后一个元素的
2、找到第一个指针和第二个指针中间的元素
3、如果该中间元素位于前面的递增数组,则中间的元素应该大于或等于第一个指针指向的元素,此时数组中的最小元素应该位于该中间元素的后面,因此把第一个指针指向该中间元素,缩小范围,移动之后第一个指针仍然位于前面的递增子数组。
4、如果该中间元素位于后面的递增子数组,则它小于或等于第二个指针指向的元素,则最小的元素应该位于中间元素的前面,则把第二个指针指向 该中间元素,缩小搜索范围,移动后的第二个指针仍然位于后面的递增数组
5、重复上述操作,最后第一个指针会指向前一个递增数组的最后一个元素,第二个指针会指向后一个递增数组的第一个元素,两个指针相邻,此时第二个指针指向的元素刚好是最小的元素。

public class Main7{
public static int min(int[] numbers){
if(numbers.length==0 || numbers==null){
throw new RuntimeException("Invalid input");
}
//初始化指针的位置
int left = 0;
int right = numbers.length-1;
int mid = 0;
//确保第一个指针在前一个递增数组,后一个指针在后一个递增数组
while(numbers[left]>numbers[right]){
if(left-right==1){
mid=right;
break;
}
//取中间位置指针
mid = (left+right)/2;
//中间指针处于前一个递增数组,左指针移动·
if(numbers[left]<=numbers[mid]){
left= mid;
}
//中间指针位于后一个递增数组,右指针移动
if(numbers[right]>=numbers[mid]){
right = mid;
}
if(numbers[right]==numbers[mid]&&numbers[mid]==numbers[left]){
return InOrder(numbers,left,right);
}
}
return numbers[mid];
}

private static int InOrder(int[] numbers, int left, int right) {
int result = numbers[left];
for(int i=left+1;i<=right;i++){
if(numbers[i]<result){
result = numbers[i];
}
}
return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: