numbers相当于是数组【1,2,3,4,5】旋转来的,我们要在【3,4,5,1,2】中找到 1 这个数(最小的)并返回
首先我们可能就会想到,这不是很简单吗,我直接 Arrays.sort(numbers) 对数组进行排序,排完之后,我直接取numbers[0]就好了呀。
嗯~好得很👍!!! 你击败了7.03% 的用户,执行时间长,内存消耗大,美得很!
这样做,性能一点都不高,那么我们怎么做才能提高性能呢
使用二分查找
这里我们需要一个low 和一个 high分别指向数组的开头和末尾,需要取到他俩的中间位置 pivot
我们把 pivot 和 high 的值进行比较。有三种情况:
①pivot > high,说明最小值在 pivot 右边,此时 我们 移动 low 让low = pivot + 1;
②pivot < high,说明最小值在 pivot 的左边,此时我们 移动 high 让 high = pivot;
③pivot = high,这种情况下是无法判断到底是那种情况,所以我们只能保守的让high 向前移动
最后 low逐渐会和 high 重合
代码:
class Solution {
public int minArray(int[] numbers) {
int low = 0;
int high = numbers.length - 1;
while(low < high){
int pivot = low + (high - low) / 2;
if(numbers[pivot] < numbers[high]){
high = pivot;
} else if(numbers[pivot] > numbers[high]){
low = pivot + 1;
} else{
high = high - 1;
}
}
return numbers[low];
}
}
本题注意事项:
1.求中间值时不要用 (a + b)/ 2,这样有时候数字过大会导致溢出
最好使用: low + (high - low)/ 2
2.数组求长度,用的是 array.length,length 后面没有()没有()没有()
3.本题最后返回的时 low,而不是 pivot ,因为pivot 一直在变,我们的循环条件是 low < high ,当low 改变自己的位置后 low = high 重合了,此时不满足循环条件,而 pivot 还停留在上一步,没有变,此时如果返回的是 pivot 结果就错了。