11 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
public int minArray(int[] numbers) {
int left=0;
int right=numbers.length-1;
int first=numbers[0];
if(first<numbers[right]) return first;
while(right>0 && numbers[right]==numbers[right-1]) right--;
while(left<right){
int mid=(left+right)/2;
if(numbers[mid]>=first){
left=mid+1;
} else {
right=mid;
}
}
return numbers[right];
}
描述
有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。
数据范围:1 \le n \le 100001≤n≤10000,数组中任意元素的值: 0 \le val \le 100000≤val≤10000
要求:空间复杂度:O(1)O(1) ,时间复杂度:O(logn)O(logn)
示例1
输入:[3,4,5,1,2]
返回值:1
示例2
输入:[3,100,200,3]
返回值:3
使用二分法。边界条件 1 :由于原数组是非递减的,可能有相同元素,数组结尾的元素可能和第一个元素相同,去掉结尾相同元素后,小于第一个元素的在数组右半边。边界条件 2 :数组是完全顺序的。
时间复杂度 o(log n) ,空间复杂度 o(1)
public int minNumberInRotateArray(int [] array) {
int left=0, right=array.length-1;
int mid, start=array[0];
if(start<array[right]) return start;
while(right>0 && array[right]==array[right-1]){
right--;
}
while(left<right){
mid=(left+right)/2;
if(array[mid]>=start){
left=mid+1;
} else {
right=mid;
}
}
return array[right];
}