题解 | #数字在升序数组中出现的次数#

数字在升序数组中出现的次数

http://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2

1、二分法     空间复杂度O(1),时间复杂度O(logn)    
 思路:二分法找目标值的begin和end,最后begin-end+1,重点是如何找begin和end

1、找begin
while(left<right){
    mid = (left+right)>>1;  //如果中点值>=目标值,那么证明目标值在(left,min]的左开又闭区间内,那么mid很有可能也是begin  //所以mid也得取到 
      if(array[mid]>=k){
            right = mid;    }  //如果中点值<目标值,那么证明目标值在(min,right)的开区间内,那left=mid+1即可 
       else{
        left = mid+1;  }
}
2、找end
while(left<right){
    mid = (left+right+1)>>1;    //如果中点值<=目标值,那么证明目标值在[mid,right)的左闭又开区间内,那么mid很有可能也是end //所以mid也得取到    
      if(array[mid]<=k)
        {
            right = mid;   
      }  //如果中点值>目标值,那么证明目标值在(left,mid)的开区间内,那right=mid-1即可    
     else{
        right = mid-1; 
      }
}
可以好好理解上面两个模版公式,其中如果出现mid-1,那么在 mid的取值要记得(left+right+1)/2,要加上1,因为要避免向下取整


public class Solution {
     public int GetNumberOfK(int [] array , int k) {
        if(array.length==0){
            return 0;
        }
        int left = 0;
        int right = array.length-1;
        int mid;
        //找左边界
        while(left<right){
            mid = (left+right)>>1;
            if(array[mid]>=k){
                right = mid;
            }
            else{
                left = mid+1;
            }
        }
         //如果目标值都没有,直接返回0
        if (array[right]!=k){
            return 0;
        }
        int l = right;

        left = 0;
        right = array.length-1;
        //找右边界

        while(left<right){
            mid = (left+right+1)>>1;
            if(array[mid]<=k){
                left = mid;
            }
            else{
                right= mid-1;
            }
        }
        int r = right;
        return r-l+1;
    }
}


全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务