题目表意不清不贴了,直接总结二分的几个经典题目模型
- 二分查找,查找的值一定存在
int left = 1, right = n;
while( left < right ){//循环终止条件是 left == right
int mid = left + (right - left >> 1 );
if( nums[mid] >= target ){//目标值在左区间 [left, mid]
right = mid;
}else{//目标值在右区间 [mid+1, rihgt]
left = mid + 1;
}
}//此时left == right,因为一定存在,肯定是
return left;
- 二分查找,查找的值不一定存在,条件处可以用
while(left<=right)
,这样就不用加最后的补丁修正了,因为区间的每一个点都会判断
int left = 1, right = n;
while( left < right ){//循环终止条件是 left == right
int mid = left + (right - left >> 1 );
if( nums[mid] >= target ){//目标值在左区间 [left, mid]
right = mid;
}else{//目标值在右区间 [mid+1, rihgt]
left = mid + 1;
}
}//此时left == right,但是这个数没有被判断过,因此加个补丁修正下
return nums[left] == target ? left : -1;
- 查找目标值第一次出现/左侧边界
int left = 1, right = n;
while( left < right ){//循环终止条件是 left == right
int mid = left + (right - left >> 1 );
if( nums[mid] >= target ){//目标值在左区间 [left, mid]
right = mid;
}else{//目标值在右区间 [mid+1, rihgt]
left = mid + 1;
}
}//此时left == right
return left;
- 查找目标值最后一次出现/右侧边界
只有这一种特殊,其他的都是一个模板
int left = 1, right = n;
while( left < right ){//循环终止条件是 left == right
int mid = left + (right - left + 1 >> 1 );// ceil()
if( nums[mid] <= target ){//目标值在右区间 [mid, right]
left = mid;
}else{//目标值在右区间 [left, mid-1]
right = mid - 1;
}
}//此时left == right
return left;