Search for a Range leetcode java

题目:

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]

从题目中获取到关键字:sorted array ,find...position, a given target value, O(logn). 

这些关键字都在提醒我们这道题的思路应该是二分查找法。 


       二分查找方法
       二分查找经常用来在有序的数列查找某个特定的位置。

       因此,应用二分查找法,这个数列必须包含以下特征:

  •  存储在数组中
  • 有序排列

     同时这道题让我们确定 starting position和ending position,这就让我们联想到之前做过的Search Insert Position一题,当无法查找到given target时,利用非递归二分查找法所得的最终low和high指针,将会指向该无法查找到的元素的左右两个元素。说不清楚看例子,例如,给定arraylist [1,2,4,5] target为3,那么通过传统非递归二分查找法,low指针将会指向4(位置为2),high指针指向2(位置为1)。

     利用这种规律,我们就能够找到target元素的左右边界。所以本题的解题思路为:

第一步,在给定数组中找到该target,记录该位置。这时我们并不关心这个target是边界还是中间值,我们只需确定,在数组中是能够找到这样一个target值。如果找不到返回{-1,-1}。为了保证时间复杂度是O(logn), 这里自然而然使用传统二分查找法实现。

第二步,确定该target的右边界。此时我们将对数组从刚才确定的那个target的pos作为起始点,到数组结束,来确定右边界。同样是使用二分查找法,当新的mid值仍然等于target值时,我们能确定该mid左半边(到pos)都是等于target,继续在右半边查找。如果新的mid值不等于target值,我们就知道右边界一定在新mid值的左半边,继续查找。最后新的high指针指向的就是右边界的位置。

第三步,确定该target的左边界。这一步与第二步对称操作,最后新的low指针指向的就是左边界的位置。

最后,返回结果数组。

代码如下:

public int[] searchRange(int[] A, int target) {
        int [] res = {-1,-1};
        if(A == null || A.length == 0)
            return res;
        
        //first iteration, find target wherever it is
        int low = 0;
        int high = A.length-1;
        int pos = 0;
        while(low <= high){
            int mid = (low + high)/2;
            pos = mid;
            if(A[mid] > target)
                high = mid - 1;
            else if(A[mid] < target)
                low = mid + 1;
            else{
                res[0] = pos;
                res[1] = pos;
                break;
            }
        }
        
        if(A[pos] != target)
            return res;
        
        //second iteration, find the right boundary of this target
        int newlow = pos;
        int newhigh = A.length-1;
        while(newlow <= newhigh){
            int newmid = (newlow+newhigh)/2;
            if(A[newmid] == target)
                newlow = newmid + 1;
            else
                newhigh = newmid - 1;
        }
        res[1] = newhigh;
        
        //third iteration, find the left boundary of this target
        newlow = 0;
        newhigh = pos;
        while(newlow <= newhigh){
            int newmid = (newlow+newhigh)/2;
            if(A[newmid] == target)
                newhigh = newmid - 1;
            else
                newlow = newmid + 1;
        }
        res[0] = newlow;
        
        return res;
    }

 Reference:http://blog.csdn.net/linhuanmars/article/details/20593391

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值