题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路1:直接遍历数组,找最小的数。
// 旋转数组的最小数字
public class Solution {
public int minNumberInRotateArray(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int min = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
}
}
缺点:没有利用旋转数组的特点。时间复杂度高。
思路2:对旋转数组来说,实际上我们可以将它划分为两个排序的子数组,而且前面子数组的元素都大于等于后面子数组的元素,并且最小元素是这两个子数组的分界。再利用二分查找的思想即可。
// 旋转数组的最小数字
public class Solution {
public int minNumberInRotateArray(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int startIndex = 0;
int endIndex = array.length - 1;
int midIndex = startIndex;
// 当数组发生了旋转时
while (array[startIndex] >= array[endIndex]) {
if (endIndex - startIndex <= 1) {
midIndex = endIndex;
break;
}
midIndex = (startIndex + endIndex) / 2;
// 如果中间的数位于数组1
if (array[startIndex] <= array[midIndex]) {
startIndex = midIndex;
}
// 如果中间的数位于数组2
if (array[endIndex] >= array[midIndex]) {
endIndex = midIndex;
}
// 如果中间的数既等于startIndex上的数 也等于endIndex上的数
if (array[midIndex] == array[startIndex] && array[midIndex] == array[endIndex]) {
return minOfArray(array, startIndex, endIndex);
}
}
return array[midIndex];
}
public int minOfArray(int[] array, int index1, int index2) {
int result = array[index1];
for (int i = index1 + 1; i < index2; i++) {
if (array[i] < result) {
result = array[i];
}
}
return result;
}
}