今天的题真的是考察最基本的二分法变形,自己第一时间没想出来,直接O(n)A掉了,没进行思考,对于已排好序的数组查找某一个值,通常需要考虑到二分法。
看完下面的就可以A掉类似的题:
先回顾一下二分法吧;
class Solution {
public int search(int[] nums, int target) {
//判断条件
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] < target ){
left = mid + 1;
}else if (nums[mid] > target){
right = mid - 1;
}else{
return mid;
}
}
return -1;
}
}
二分查找即折半查找,进行区间的范围性缩小查找。基本很简单没什么说的
在递增的数组中进行旋转,找出旋转之后的最小数字
首先想到递增数组,找出最小数字,二分查找直接上;但是会有一个小细节,我们都知道 mid = left + (right - left)/2 mid是左边小 右边大;但是一个数组进行旋转之后,可能会发生变化,所以这个需要进行以right为标准;
1.当 nums[mid] > nums[right]时 说明mid的右半部分都是大数值,小数值在左半区间,将 right = mid 注意这边是 mid 在最小值区间内 在最小值区间内中每一个数字都有可能是最小值,并且数组还是可重复的
2.当nums[mid] < nums[right] 说明最小值在右半边区间 将left = mid + 1注意这边是 left = mid + 1 因为nums[mid] < nums[right] 所以mid处值必定不是最小值,可直接跳过
3. 当nums[mid] = nums[right] 说明 出现的重复值,将right = right -1,缩小范围空间
//二分法进行查找
public static int minArray(int[] numbers) {
int left = 0;
int right = numbers.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
//判断最小值是否在左区间
if (numbers[mid] < numbers[right]){
right = mid;
}else if (numbers[mid] > numbers[right]){
//判断最小值是否在右区间
left = mid + 1;
}else if (numbers[mid] == numbers[right]){
//重复值判断
right = right - 1;
}
}
return numbers[left];
}