34. Search for a Range [LeetCode]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jacky_chenjp/article/details/71426415

Given an array of integers sorted in ascending order, 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].


由题意,是要求:在一个给定的非降序整型数组nums中,给定一个目标值target,求出数组中该值的起始位置索引和结束位置索引。要求算法的时间复杂度为O(log N)。


分析:看到时间复杂度为O(log N),立即联想到这是个典型的二分法查找的应用问题。不过在本题中,因为要求得左右边界位置,不能简单地使用二分查找法,而需要进行一定的修改。

修改的方法是:改进二分查找法,终止条件变为:left < right - 1;而当前值与目标值相等时,求左边界就把当前索引下标赋给 right,求右边界就把当前索引下标赋给 left,即让 left--right 区间向目标边界靠拢。这样,结束的时候,会有2个值供我们判断使用。这样做的最大的好处是,不用处理各种越界问题。编写代码时要注意,求左边界时,优先判断 left 是否为边界,再判断 right;而求右边界时,优先判断 right 是否为边界,再判断 left。


扫描二维码关注公众号,回复: 3511234 查看本文章

给出AC的JAVA代码如下:


public class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        int left = 0;
        int right = len-1;
        int[] res = {-1, -1};
        
        // corner case
        if (len==0||nums==null) {
            return res;
        }
        
        // binary search loop, when loop end, there will be 2 elements between left and right index
        while (left<right-1) {
            // search the left bound
            int mid = (right+left)/2;
            if(nums[mid] == target){
                right = mid;
            } else if(nums[mid] < target) {
                left = mid;
            } else {
                right = mid;
            }
        }
        
        // set the left bound
        if (nums[left]==target) {
            res[0]=left;
        } else if (nums[right]==target) {
            res[0]=right;
        } else {
            return res;
        }
        
        // reset the left and right index
        left=0;
        right=len-1;
        
        // search the right bound
        while (left<right-1) {
            int mid=(right+left)/2;
            if (nums[mid]==target) {
                left=mid;
            } else if (nums[mid] < target) {
                left=mid;
            } else {
                right = mid;
            }
        }
        
        // set the right bound
        if (nums[right]==target) {
            res[1]=right;
        } else if (nums[left]==target) {
            res[1]=left;
        } else {
            return res;
        }
        
        return res;
    }
}


猜你喜欢

转载自blog.csdn.net/Jacky_chenjp/article/details/71426415