这道题简单来说就是二分法的一个变体,但是难点在于异常情况的考虑。
- 将前面0个数搬到数组后面,也能称其为旋转数组。
- 0111数组的旋转数组1011,1101
对于第一种情况,因为旋转之前,数组已经是有序的,所以直接输出第一个数即可。
对于第二种情况,则只能顺序遍历。
代码如下:
public int findMin(int[] nums) {
if (nums == null || nums.length == 0) {
return -1;
}
// 把第0个数据旋转到数组后面
int first = 0;
int last = nums.length - 1;
int mid = first;
while (nums[first] >= nums[last]) {
if (first + 1 == last) {
return nums[last];
}
// 针对情况二,只能顺序遍历
if (nums[first] == nums[last] && nums[last] == nums[mid]) {
return MinInOrder(nums);
}
if (nums[mid] > nums[first]) {
first = mid;
} else if (nums[mid] < nums[last]) {
last = mid;
}
mid = (last + first) / 2;
}
return nums[mid];
}
private int MinInOrder(int[] nums) {
int target = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] < target) {
target = nums[i];
}
}
return target;
}
最优情况下时间复杂度O(logn),最差时间复杂度O(n)。
https://blog.csdn.net/u010452388/article/details/80891462