search for a range(找出一个数在数组中开始和结束位置)

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

这一题是从一个有序数组中找出一个数的开始位置和结束位置。这个题目跟求数组中一个数的个数一样(出现次数)。

平常的做法,直接遍历 ,复杂的是O(n),因为有序,用二分查找。复杂度为O(logn)。

像这种查找,因为有重复数字,可以分两步。

1,找出target,如果有多个,求出第一次出现的那个(有序以后)。

2,找出最后一次出现的那个。

如果求个数,则两者相减。。所以这两个步骤都要掌握。

见下面的标记。。一定记住

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] result=new int[2];
        if(nums==null||nums.length==0){
            result[0]=-1;
            result[1]=-1;
            return result;
        } 
        
        int left=0;
        int right=nums.length-1;
        //查找最左边的位置
        while(left<right){ 
            int mid=(left+right)/2;
            if(nums[mid]>target)
                right=mid-1;
            else if(nums[mid]<target)
                left=mid+1;
            else
                right=mid;   //这一步。。求最最左边的,当相等时,将右指针移到mid上
        }
        if(nums[left]!=target){  //用left是因为:当存在这样的数时,left=right了,一样;不存在时,right可能到-1,所以用left。
            result[0]=-1;
            result[1]=-1;
            return result;
        }
        
        result[0]=left;
        //查找最右边位置
        left=0;right=nums.length-1;
        while(left<right){
           int mid=(left+right+1)/2;  //这一步,重点之一
             if(nums[mid]>target)
                right=mid-1;
            else if(nums[mid]<target)
                left=mid+1;
            else
                left=mid;    //这一步。
        }
    //因为上面已经确保了存在,所以这里不需要再判断 result[
1]=right; //用right是因为:当存在这样的数时,left=right了,一样;不存在时,left可能到length,所以用right。 return result; } }
原文地址:https://www.cnblogs.com/xiaolovewei/p/8136801.html