[leetcode] Search for a Range

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

https://oj.leetcode.com/problems/search-for-a-range/

排过序的数组,要求时间是logn,一看就是要用binary search。 值得一读值得一读2

思路1:binary search到元素,然后向两边扩展找相同元素,最坏情况O(n).

思路2:对binary search稍微修改,然后进行两次binary search,分别定位指定元素的下界和上界。

思路2代码:

已删除

 第二遍记录:

  两个函数的名字改一下分别叫:lowerBound 和 upperBound。

public class Solution {
    public int[] searchRange(int[] A, int target) {
        if (A == null || A.length == 0)
            return new int[] { -1, -1 };
        int n = A.length;
        int floor = lowerBound(A, target);
        int ceiling = upperBound(A, target);
        if (ceiling > floor)
            return new int[] { floor, ceiling - 1 };

        else
            return new int[] { -1, -1 };
    }

    public int lowerBound(int[] a, int x) {
        int left = 0;
        int right = a.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (x > a[mid]) {
                left = mid + 1;
            } else if (x <= a[mid]) {
                right = mid - 1;
            }
        }
        return left;
    }

    public int upperBound(int[] a, int x) {
        int left = 0;
        int right = a.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (x >= a[mid]) {
                left = mid + 1;
            } else if (x < a[mid]) {
                right = mid - 1;
            }
        }
        return left;
    }

}

 

第N遍,

分析为什么left是最终需要的坐标,考虑最后left和right相交的两种情况(lrm都在最后一个元素,lrm在最后两个元素),分情况讨论。

 

 

第n遍,尝试使用binary search template 2, 注意upperbound对于大于所有数组元素的target需要返回长度加一的index,所以 r = nums.length instead of r = nums.length-1;

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums == null || nums.length == 0){
            return new int[]{-1,-1};
        }
        int lowerBound = lowerBound(nums,target);
        if(lowerBound == -1){
            return new int[]{-1,-1};
        }
        int upperBound = upperBound(nums,target);
        return new int[]{lowerBound, upperBound-1};
        
    }
    
    private int lowerBound(int[] nums, int target){
        int l = 0, r = nums.length-1;
        
        while(l<r){
            int mid = l + (r-l)/2;
            if(nums[mid]>=target){
                r = mid;
            }else{
                l = mid+1;
            }
        }
        return nums[l]==target?l:-1;
    }
    
    private int upperBound(int[] nums, int target){
        int l =0, r = nums.length;
        
        while(l<r){
            int mid = l + (r-l)/2;
            if(nums[mid]<=target){
                l = mid+1;
            }else{
                r = mid;
            }
        }
        return l;
    }
    
}

  

 

posted @ 2014-06-26 19:43  jdflyfly  阅读(203)  评论(1编辑  收藏  举报