<LeetCode> 题14:二分查找

题目描述:

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。
例如:在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2。

思路:

首先比较中间的数和要查找的数,如果关键字(要查找的数)小于中间的数,那么在数组的左半部分继续查找,如果关键字大于中间的数,那么在数组的右半部分继续查找,如果关键字和中间的数相等,那么比较中间数字的前一个数字是否和关键字相等,如果不相等,那么当前的中间索引就是第一次出现的索引,如果相等,那么继续在前半部分查找。

代码1(数组方式):

int GetFirstTarget(int arr[],int k,int start,int end)  
{  
    if (start > end)  
    {  
        return -1;  
    }  

    //中间索引  
    int mid = start + ( (end-start) >> 1);  
    int midData = arr[mid];  

    while (start <= end)  
    {  
        if (k > midData)  
        {  
            start = mid+1;  
        }  

        else if (k < midData)  
        {  
            end = mid-1;  
        }  

        else if (k == midData)  
        {  
            if ((k != arr[mid-1] && mid > 0) || mid == 0)  
            {  
                return mid;  
            }  

            else  
                end = mid-1;  
        }  

        //更新中间值的索引和值  
        mid = start + ( (end-start) >> 1);  
        midData = arr[mid];  
    }  

    return -1;  
}  

代码2(向量方式):

int GetFirstTarget(vector<int> &arr,int k)  
{  
    if(arr.size() == 0)
    {
        return -1;
    }

    int start = 0;
    int end = arr.size() - 1;
    int mid;

    while (start + 1 < end)
    {
        mid = start + (end - start) / 2;
        if (arr[mid] == k)
        {
            end = mid;
        } 
        else if (arr[mid] < k) 
        {
            start = mid;
        }
        else if (arr[mid] > k)
        {
            end = mid;
        }
    }

    if (arr[start] == k)
    {
        return start;
    }
    if (arr[end] == k) 
    {
        return end;
    }

    return -1; 
}

拓展:寻找最后一次出现的索引

int GetLastTarget(int arr[],int len, int k,int start,int end)  
{  
    if (start > end)  
    {  
        return -1;  
    }  

    //中间索引  
    int mid = start + ( (end-start) >> 1);  
    int midData = arr[mid];  

    while (start <= end)  
    {  
        if (k > midData)  
        {  
            start = mid+1;  
        }  

        else if (k < midData)  
        {  
            end = mid-1;  
        }  

        else if (k == midData)  
        {  
            if ((k != arr[mid+1] && mid < 0) || mid == len - 1)  
            {  
                return mid;  
            }  

            else  
                end = mid + 1;  
        }  

        //更新中间值的索引和值  
        mid = start + ( (end-start) >> 1);  
        midData = arr[mid];  
    }  

    return -1;  
} 

ps:完整测试程序请看我的代码片:binarySearch.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值