您的位置:首页 > 其它

leetcode 刷题之路 21 Search for a Range

2014-07-28 08:08 225 查看
Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return
[-1, -1]
.

For example,

Given
[5, 7, 7, 8, 8, 10]
and target value 8,

return
[3, 4]
.

给定一个数组,要求查找一个目标数字在数组中的下标范围并返回,要求时间复杂度为O(logn),如果数组中无该数字则返回[-1,-1]。

题目要求时间复杂度为O(logn),自然会想到用二分查找法来解决这个问题,传统的二分查找法在找到一个目标值后就结束查找,因此我们需要在此基础上做一些改进,使得对于包含重复的目标数字的数组,算法可以确定的找到目标数字的上下边界。

首先我们要了解一个有用的知识点:给定整型变量lower,mid,upper,且lower<=upper,循环执行语句:

mid=(lower+upper)/2

upper=mid

upper最终会回落到lower,即upper最终会等于lower。

寻找目标数字的左边界,可以写出下面的代码:

while(lower<upper)
        {
            mid=(lower+upper)/2;
            if(A[mid]<target)
                lower=mid+1;
            else
                upper=mid;
        }
当mid位于目标数字左边时,lower在mid的位置上向右移动一个位置,当mid位于目标数字中时,upper=mid=(lower+upper)/2向lower回落,他们相遇的位置就是目标数字的起始位置。

同理,寻找目标数字的右边界,有以下代码:

while(lower<upper)
        {
            mid=(lower+upper)/2;
            if(A[mid]>target)
                upper=mid;
            else
                lower=mid+1;
        }
lower和upper最终相遇的位置在目标数字右边界的下一个位置。

测试通过代码:

class Solution {
public:
vector<int> searchRange(int A[], int n, int target)
{
vector<int> vi(2,-1);
int lower=0;
int upper=n;
int mid;
while(lower<upper) { mid=(lower+upper)/2; if(A[mid]<target) lower=mid+1; else upper=mid; }
if(A[lower]!=target)
return vi;
vi[0]=lower;

upper=n;
while(lower<upper) { mid=(lower+upper)/2; if(A[mid]>target) upper=mid; else lower=mid+1; }
vi[1]=upper-1;
return vi;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: