旋转数组的最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路
先处理两种特殊情况。搜索范围头元素小于搜索范围尾元素,直接得出结果。搜索范围头元素、中间元素、尾元素相等,退化为顺序查找。然后根据搜索范围的头元素与中间元素的大小关系,缩小搜索范围。缩小到搜索范围只剩1到2个元素时得出结果。缩小搜索范围的核心思想是二分法。
代码
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
// 处理特殊值
if (array == null) {
return 0;
}
if (array.length == 0) {
return 0;
}
// 初始化数组搜索范围
int arrayLength = array.length;
int firstIndex = 0;
int lastIndex = arrayLength - 1;
while (lastIndex - firstIndex > 0) {
int firstValue = array[firstIndex];
int lastValue = array[lastIndex];
// 搜索范围剩余1个或2个元素时,直接得出结果
if (lastIndex == firstIndex) {
return firstValue;
} else if (lastIndex - firstIndex == 1) {
if (firstValue < lastValue) {
return firstValue;
} else {
return lastValue;
}
}
int middleIndex = (firstIndex + lastIndex) / 2;
int middleValue = array[middleIndex];
if (firstValue < lastValue) {
// 搜索范围头元素小于搜索范围尾元素,直接得出结果
return firstValue;
} else if (firstValue == lastValue && firstValue == middleValue) {
// 搜索范围头元素、中间元素、尾元素相等,退化为顺序查找
return minNumberInRotateArrayBySequenceSearch(array);
}
// 根据搜索范围的头元素与中间元素的大小关系,缩小搜索范围
if (middleValue < firstValue) {
lastIndex = middleIndex;
} else {
firstIndex = middleIndex;
}
}
// 不会执行到这里
return 0;
}
// 顺序查找数组中的最小值
private int minNumberInRotateArrayBySequenceSearch(int [] array) {
int min = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
}
}
PREVIOUS剑指Offer 面试题07:用两个栈实现队列