1.在有序不重复元素中查找:
public int BS(int[] num,int x) {
int low = 0,high = num.length;
int mid;
while(low <= high){
mid = (low + high)/2;
if(x == num[mid]) return mid;
else if(num[mid] > x) high = mid -1;
else low = mid + 1;
}
return -1;
}
2.存在重复查找第一个>=x的元素:
public int BS(int[] num,int x) {
int low = 0,high = num.length;
int mid;
while(low < high){
mid = (low + high)/2;
if(num[mid] >= x) high = mid;
else low = mid + 1;
}
return low;
}
3.存在重复查找第一个>x的元素:
public int BS(int[] num,int x) {
int low = 0,high = num.length;
int mid;
while(low < high){
mid = (low + high)/2;
if(num[mid] > x) high = mid;
else low = mid + 1;
}
return low;
}
4.查找旋转排序数组中指定值:
//如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的
public int search(int[] nums, int target) {
if (nums.length == 0) return -1;
int low = 0, high = nums.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < nums[high]) {
if (nums[mid] < target && nums[high] >= target) low = mid + 1;
else high = mid - 1;
} else {
if (nums[low] <= target && nums[mid] > target) high = mid - 1;
else low = mid + 1;
}
}
return -1;
}
5.查找旋转排序数组中最小值:
/*
low指针总是指向前面递增数组的元素,而high指针总是指向后面递增数组的元素。最终low指针将指向前面子数组的最后一个元素,
而high指针会指向后面子数组的第一个元素。也就是它们最终会指向两个相邻的元素,而high指针指向的刚好是最小的元素。
*/
public int search(int [] nums) {
if(nums.length == 0) return 0;
int low = 0,high = nums.length-1;
int mid = 0;//如果是有序数组直接返回第一个元素
while(nums[low] >= nums[high]){
if(high-low == 1){
mid = high;
break;
}
mid = (low+high)/2;
if (nums[mid] >= nums[low]) low = mid;
else if(nums[mid] <= nums[high])high = mid;
}
return nums[mid];
}
注意事项:
a:if分支结构中出现low = mid或high = mid的情况,循环条件应该为low < high,以避免可能出现的死循环。
b:当num.length较大时,low+high有可能超出int范围,此时应该写为mid = low/2 + high/2。
c:while循环中如果return了,循环外面只需要return -1即可。