题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路:
将旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面子数组的元素。并且最小的元素刚好是这两个数组的分界线。可以使用二分查找的方法来寻找这个最小的元素。
首先,定义三个变量,分别代表数组中第一个元素的下标、中间元素的下标和最后一个元素的下标。
按照旋转规则,数组中的第一个元素应该大于等于数组中的最后一个元素,这就是循环的条件。
接下来,分为三种情况:
(1)如果最后两个数组下标相邻,则直接返回第二个数组下标的元素;
(2)如果此时数组中的第一个元素、中间元素和最后一个元素都相等 ,则只能顺序遍历数组寻找数组中的最小的元素;
(3)如果数组中间元素的值大于数组中的第一个元素的值,需要将指示第一个元素的下标更换为指示中间元素的下标,如果数组中间的元素值小于数组中第一个元素的值,则需要将指示最后一个元素的下标更换为中间元素的下标,这样就可以缩小查找的范围,减少查找的算法时间复杂度。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int[] array) {
if (array.length == 0) {
return 0;
}
int len = array.length;
int pri = 0;
int last = len - 1;
int mid = 0;
while (array[pri] >= array[last]) {
if (last - pri == 1) {
mid = last;
break;
}
mid = (pri+last) / 2;
if(array[pri]==array[last]&&array[pri]==array[mid]){
int result = array[pri];
for(int i = pri +1;i<=last;i++){
if(result>array[i]){
result = array[i];
}
}
return result;
}
if (array[mid] >= array[pri]) {
pri = mid;
} else if (array[mid] <= array[pri]) {
last = mid;
}
}
return array[mid];
}
}