问题描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路
将数组旋转之后,可以看做把原来的数组分成了两个不递减数组,{3, 4,5}和{1, 2},而最小的数“1”恰恰是两个数组的分界点。
对于一个排序数组的查找,可以用二分查找,本题的查找同样可以用二分查找,只是需要判断mid是位于第一个数组还是第二个数组。
一般来说,第一个数组中的数 >= 第一个数, 第二个数组中的数 <= 第二个数。可以根据这个来判断是位于哪个数组。同样要注意的是,因为是不递减,所以要考虑一种特殊情况:
{1,0,1,1,1,}
此时无法判断中间数是属于哪一个数组的,只能靠顺序查找的方法找出最后的结果。
代码实现:
import java.util.ArrayList;
public class Solution {
public static int minNumberInRotateArray(int [] array) {
if(array == null || array.length == 0) {
return 0;
}
int length = array.length;
int first = 0;
int second = length - 1;
int indexMeddle = 0;
while(first < second) {
if(second - first == 1) {
indexMeddle = second;
break;
}
indexMeddle = (second + first)/2;
if(array[first] == array[second] && array[first] == array[indexMeddle]) {
return getMiddle(array, first, second);
}
if(array[first] <= array[indexMeddle])
first = indexMeddle;
else if(array[second] >= array[indexMeddle])
second = indexMeddle;
}
return array[indexMeddle];
}
public static int getMiddle(int [] array, int first, int second) {
int res = array[first];
for(int i = first + 1; i <= second; i++) {
if(array[i] < res)
res = array[i];
}
return res;
}
}