二分查找的模板:
class Solution {
public int search(int[] nums, int target) {
int length = nums.length;
if(length == 0){
return -1;
}
int left = 0;
int right = length-1;
while(left<=right){
int mid= (left+right)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid]<=target){
left = mid + 1;
}else if(nums[mid]>target){
right = mid - 1;
}
}
return -1;
}
}
但是这种一般的写法在遇到以下的问题的时候存在一些问题
这个时候,数组中待查找的元素个数可能不止一个。
这里介绍一种二分查找的另外一种写法,利用减治法的思想来写二分查找:
从代码的形式上来看,与上面是有所不同的,只有这两种情况。
当出现死循环的时候,原因是,用这种取中间数的方式只能取到左边,当只有最后两个数的时候,目标落在右边的时候,是取不到的,这个时候只需要在括号里再+1;
class Solution {
public int searchInsert(int[] nums, int target) {
int length = nums.length;
if(length == 0){
return 0;
}
if(nums[length-1]<target){
return length;
}
int left = 0;
int right = length-1;
while(left < right){
int mid = left +(right - left)/2;
if(nums[mid]<target){
left = mid+1;
}else {
right = mid;
}
}
return left;
}
}
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] result = new int[2];
int first = findFirsttarget(nums,target);
if(first == -1){
result[0] = -1;
result[1] = -1;
}
int last = findLasttarget(nums,target);
result[0] = first;
result[1] = last;
return result;
}
public int findFirsttarget(int[] nums,int target){
int length = nums.length;
if(length == 0){
return -1;
}
int left = 0;
int right = length-1;
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid]<target){
left = mid+1;
}else{
right = mid;
}
}
if(nums[left] == target){
return left;
}
return -1;
}
public int findLasttarget(int[] nums,int target){
int length = nums.length;
if(length == 0){
return -1;
}
int left = 0;
int right = length-1;
while(left < right){
int mid = left + (right - left+1)/2;
if(nums[mid]>target){
right = mid-1;
}else{
left = mid;
}
}
if(nums[left] == target){
return left;
}
return -1;
}
}