题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解法一:直接遍历数组,但时间复杂度为O(n)
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length == 0)
return 0;
int tag = 0;
for(int i=1;i<array.length;++i)
{
if(array[i] < array[i-1])
{
tag = i;
break;
}
}
return array[tag];
}
}
解法二:利用输入的旋转数组的特性,实际上,旋转之后的数组可以分为两个排序的子数组,而且前面子数组的元素都大于或者等于后面子数组的元素,最小的元素刚好是这两个子数组的分界线。在排序的子数组中使用二分查找,时间复杂度为O(logn)。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array)
{
if(array == null || array.length == 0)
return 0;
int begin = 0;
int end = array.length - 1;
int middle = 0;
while(array[begin] >= array[end])
{
if(begin - end == 1)
{
middle = end;
break;
}
middle = (begin + end) / 2;
//如果下表为begin、end、middle指向的三个数字相等,只能顺序查找
if(array[begin] == array[end] && array[end] == array[middle])
return MinInOrder(array, begin, end);
if(array[middle] >= array[begin])
begin = middle;
else if(array[middle] <= array[end])
end = middle;
}
return array[middle];
}
int MinInOrder(int[] array, int begin, int end)
{
int result = array[begin];
for(int i=begin+1;i<=end;++i)
{
if(result > array[i])
{
result = array[i];
}
}
return result;
}
}