码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode]Search for a Range

时间:2015-07-04 12:45:48      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:

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].

[LeetCode Source]

思路:

1)先用二分查找找到点,然后再左右扩展,找到范围。如果有m个要搜寻点,算法复杂度为O(lgN+m),m<=N。最好的情况下是O(lgN),只有一个点的时候;最差情况O(N),全是要搜寻点的时候。这种做法可以Ac。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> result(2,-1);
        int left = 0;
        int right = nums.size()-1;
        int mid = 0;
        int first = -1;
        int second = -1;
        while(left<=right){
            mid = left+(right-left)/2;
            if(nums[mid] > target)
                right = mid - 1;
            if(nums[mid] < target)
                left = mid + 1;
            if(nums[mid] == target){
                first = mid;
                second = mid;
                break;
            }
        }
        for(int i=mid-1;i>=0;i--){
            if(nums[i]==target)
                first--;
            else break;
        }
        for(int i=mid+1;i<nums.size();++i){
            if(nums[i]==target)
                second++;
            else break;
        }
        result[0] = first;
        result[1] = second;
        return result;
    }
};

2)可能是最优解法。两次二分查找,一次是找到左边界点,第二次找到右边界点。

找左边界点时,修改二分查找的规则,如果找到点,还要继续往左二分直到找到左边界点;

找右边界点时,同理。

特别注意break的处理,当明显找不到点时break掉循环,对于找左边界点就是nums[right]<target。

这种解法复杂度是O(lgN)

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
    int hit = -1;
    int left=0, right=nums.size() - 1;
    int first = 0, second = 0;

    vector<int> ret(2, -1);

    while(left <= right)
    {
        int mid = left + (right - left) / 2;
        if(nums[right] < target)    break;

        if(nums[mid] >= target)
        {
            if(nums[mid] == target) hit = mid;
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }
    if(hit == -1)   return ret;
    first = hit;

    left = hit;
    right = nums.size() - 1;
    hit = -1;

    while(left <= right)
    {
        int mid = left + (right - left) / 2;
        if(nums[left] > target)    break;

        if(nums[mid] <= target)
        {
            if(nums[mid] == target) hit = mid;
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }
    if(hit == -1)   return ret;
    second = hit;

    ret[0] = first;
    ret[1] = second;

    return ret;
}
};



版权声明:本文为博主原创文章,未经博主允许不得转载。

[LeetCode]Search for a Range

标签:

原文地址:http://blog.csdn.net/ciaoliang/article/details/46754043

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!