旋转数组的最小数字
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
解题思路
二分查找
-
根据数组的特点,利用二分法来做,每次取中间值
numbers[mid]
,分三种情况进行讨论:numbers[mid] > numbers[right]
,此时说明旋转的部分在mid
右侧numbers[mid] < numbers[right]
,此时说明mid
右边一定不包含最小值,numbers[mid]
有可能是,也有可能在mid
左侧-
numbers[mid] == numbers[right]
,此时不能确定最小值在m
的哪一侧,但可以确定的是,把numbers[right]
舍弃掉,并不影响结果Case 1:
[1, 0, 1, 1, 1]
,最小值在mid = 2
的左侧Case 2:
[1, 1, 1, 0, 1]
,最小值在mid = 2
的右侧
时间复杂度:
O(logn)
,空间复杂度:O(1)
class Solution {
public int minArray(int[] numbers) {
int left = 0, right = numbers.length - 1;
while (left < right) {
// 防止 left + right 溢出
// 或者用 mid = left + (right - left) >> 1;
int mid = ((left + right) >>> 1);
if (numbers[mid] > numbers[right]) {
// 下一轮搜索区间是 [mid + 1, right]
left = mid + 1;
} else if (numbers[mid] < numbers[right]) {
// 下一轮搜索区间是 [left, mid]
right = mid;
} else {
// 下一轮搜索区间是 [left, right - 1]
right--;
}
}
return numbers[left];
}
}