题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
我一开始想的是直接升序排列然后输出第一个元素,但是我看了大佬的解答,那个复杂度略高,于是我才发现也可以使用二分搜索法进行寻找。
思想就是找右边升序序列的最小值。为什么不找左边,我觉得是因为左边可能有重复元素,可能会出现错误。跟二分搜索一样,当 i == j 的时候循环停止,将中间的数与最右边数进行比较,为什么和最右边比较,因为我们要找j的初始值肯定在右序列中啊~如果比他大,那么就将i变为m+1,如果比他小,那么就将j变为m。然后出现了最复杂的情况,就是相等的时候,因为可以出现重复元素,所以相等的时候采取j变为j-1的策略,因为即使j-1,但是j如果是旋转点的话还是在[i,j]序列中的,因为num[m]==num[j]
class Solution {
public int minArray(int[] numbers) {
int i = 0;
int j = numbers.length - 1;
while(i < j){
int m = (i + j) / 2;
if(numbers[m] < numbers[j]) j = m ;
else if(numbers[m] > numbers[j]) i = m + 1 ;
else j--;
}
return numbers[i];
}
}