【LeetCode & 剑指offer刷题】查找与排序题1:二分查找小结

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

二分查找小结

/* 类型1
功能:查找和目标值完全相等的数
返回:如果存在,返回对应位置索引,否则返回-1
 
例:
    [2, 4, 5, 6, 9]target = 6,返回索引3
*/
int find(vector<int>& a, int target)
{
    int left = 0, right = a.size(); //stl中喜欢把end指向末尾后一个元素的做法类似
    while (left < right)
    {
        int mid = left + (right - left) / 2;
        if (a[mid] < target)
            left = mid + 1;
        else if (a[mid] > target)
            right = mid;
        else
            return mid;
    }
    return -1;
}
/*
类型1写法二
*/
int binarysearch(vector<int>& a, int k)
{
    int left = 0;
    int right = a.size() - 1;
    while(left <= right)
    {
        int mid = (left+right) / 2;
        if(a[mid] < k) //k较a[mid]大时,在右半区间找
            left = mid + 1;
        else if(a[mid] > k) //k较小时,在左半区间找
            right = mid - 1;
        else //若想等则返回mid
            return mid;
    }
    return -1; //找不到时返回-1
}
 
 
/* 类型2
功能:查找第一个大于等于目标值的数,可变形为查找最后一个小于目标值的数(返回right-1
完成stllower_bound的功能
返回:如果存在,返回对应位置索引,否则返回末尾索引end, 数组 [begin,end)
 
例:
    [2, 4, 5, 6, 9]target = 3,返回数字4的位置;
    [0, 1, 1, 1, 1]target = 1,返回第一个数字1的位置
过程:
    left = 0,right = 5
    mid = 2,a[2] = 1, right = mid = 2
    mid = 1,a[1] = 1, right = mid = 1
    mid = 0,a[0] < 1, left = mid+1 = 1 = right  跳出循环,然后return
 
n1         n2(left)     n3(right)
<a[mid]                 >=a[mid]
 
当a[mid]小于target时,left更新为mid+1,也就是说left之前的数一定是小于target的
right更新的地方一定是≥target的
而循环会在left=right时退出,故right处的值是第一个≥target的数
*/
int my_lowerbound(vector<int>& a, int target)
{
    int left = 0, right = a.size(); //stl中喜欢把end指向末尾后一个元素的做法类似
    while (left < right)
    {
        int mid = left + (right - left) / 2;
        if (a[mid] < target)
            left = mid + 1;
        else            //没有单独考虑等于的情况
            right = mid;
    }
    return right;
}
 
/* 类型3
功能:查找第一个大于目标值的数,可变形为查找最后一个小于等于目标值的数(返回right-1
完成stlupper_bound的功能
返回:如果存在,返回对应位置索引,否则返回末尾索引end, 数组 [begin,end)
 
例:
    [2, 4, 5, 6, 9]target = 3,返回数字4的位置;
    [0, 1, 1, 1, 1]target = 1,返回坐标5,通过对比返回的坐标和数组的长度,我们就知道是否存在这样一个大于目标值的数
过程:
    left = 0,right = 5
    mid = 2,a[2] = 1, left = mid+1 = 3
    mid = 4,a[4] = 1, left = mid+1 = 3 = right 跳出循环,然后return
*/
int my_upperbound(vector<int>& a, int target)
{
    int left = 0, right = a.size(); //stl中喜欢把end指向末尾后一个元素的做法类似
    while (left < right)
    {
        int mid = left + (right - left) / 2;
        if (a[mid] <= target)
            left = mid + 1;
        else
            right = mid;
    }
    return right;
}
 
 

 

posted @ 2019-01-05 20:06  wikiwen  阅读(267)  评论(0编辑  收藏  举报