基本概念
-
Binary Search
二分查找也称折半查找,它是一种效率较高的查找方法;使用二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
-
基本原理
①.查找:因为序列已经单调且有序排列,从中间位置开始比较,一次可以排除一半的数据,不断缩小查找范围;
②.终止条件:找到了目标值,或者左右边界已经构不成有效区间;
③.左右边界:理想情况下右边界不断缩小以逼近目标位置,左边界不断增大以逼近目标位置。
查找等于 key 的元素位置
// target == key
// 找到目标值或者构不成有效区间就返回
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
int mid = left + (right - left )/2;//防止相加后超 int 范围
if( nums[mid] == target )//找到了
{
return mid;
}
else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
{
left = mid +1;
}
else if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
{
right = mid -1;
}
return -1;//没有找到目标值
}
}
查找第一个大于 key 的元素位置
// target > key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
int mid = left + (right - left )/2;//防止相加后超 int 范围
if( nums[mid] <= target )// mid 值小,需要增加左边界,且 mid 位置已排除
{
left = mid +1;
}
else if( nums[mid] > target )// 找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
{
right = mid -1;
}
}
return left <= nums.size()-1 ? left :-1;//判断是否出界
}
查找第一个大于或者等于 key 的元素位置
// target >= key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
int mid = left + (right - left )/2;//防止相加后超 int 范围
if( nums[mid] >= target )//找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
{
right = mid -1;
}
else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
{
left = mid +1;
}
}
return left <= nums.size()-1 ? left :-1;//判断是否出界
}
查找第一个等于 key 的元素位置
// target == key
// 不断缩小右边界使其不断逼近目标位置,当最后一下缩小位置后恰好不满足条件,因此返回 right+1 ,即 left
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
int mid = left + (right - left )/2;//防止相加后超 int 范围
if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
{
right = mid -1;
}
else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
{
left = mid +1;
}
if( nums[mid] == target )//找到了一个符合条件的值,缩小右边界,看有没更符合条件的值
{
right = mid -1;
}
return left <= nums.size()-1 && nums[left] == target ? left :-1;//判断是否出界
}
}
查找最后一个小于 key 的元素位置
// target < key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
if( nums[mid] >= target )// mid 值大,需要缩小右边界,且 mid 位置已排除
{
right = mid -1;
}
else if( nums[mid] < target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
{
left = mid +1;
}
}
return right >= 0 ? right :-1;//判断是否出界
}
查找最后一个小于或者等于 key 的元素位置
// target <= key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
{
right = mid -1;
}
else if( nums[mid] <= target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
{
left = mid +1;
}
}
return right >= 0 ? right :-1;//判断是否出界
}
查找最后一个等于 key 的元素位置
// target == key
// 不断增大左边界使其不断逼近目标位置,当最后一下增加位置后恰好不满足条件,因此返回 left-1 ,即 right
int binarySearch( vector<int>& nums, int target)
{
int letft = 0;
int right = nums.size()-1;//查找区间范围 [left,right]
whiel(left <= right)// 结束条件 left = right+1 时,[right+1,right] 构不成合理区间范围
{
if( nums[mid] > target )// mid 值大,需要缩小右边界,且 mid 位置已排除
{
right = mid -1;
}
else if( nums[mid] == target )//找到了一个符合条件的值,增加左边界,看有没更符合条件的值
{
left = mid +1;
}
else if( nums[mid] < target )// mid 值小,需要增加左边界,且 mid 位置已排除
{
left = mid +1;
}
}
return right >= 0 && nums[right] == target ? right :-1;//判断是否出界
}