[剑指offer] 数字在排序数组当中出现的次数
[剑指offer] 数字在排序数组当中出现的次数 P221
11122222333
使用二分搜索查找target的开始indexbegin和结束indexend,则个数是indexend - indexbegin + 1;
找到开始位置
getBeginIndex(int [] num, int target):
int left =0;
int right = num.length-1;
while(left<=right){
if(left<right) return -1;没有这个元素target
int mid = (left + right)/2;
if(num[mid]==target){
if(mid==0||num[mid-]!=target) return mid;
right = mid-1;
}else if(num[mid]> target){
right = mid-1;
}else{
left = mid+1;
}
}
return -1;
找到结束位置
getEndIndex(int [] num ,int target):
int left = 0;
int right = num.length-1;
while(left<=right):
if(left>right) return -1;
int mid = (right+left)/2;
if(num[mid]==target){
if(mid==num.length-1||num[mid+1]!=target) return mid;
left = mid+1;
}else if(num[mid]>target){
right = mid-1;
}else{
left = mid+1;
}
return -1;
调用上面的方法求左右边界
targetlength(int [] num,int target):
int left = getBeginIndex(num,target);
int right = getEndIndex(num,target);
if(left!=-1&&right!=-1):
return[0]=left;
return[1]=right;
else
return error;
end
上面两个方法都是O(logN)的,所以总的复杂度是O(logN)
leetcode 当中的一个题目使用这里的方法
1 public class Solution { 2 private int searchL(int [] nums,int target){ 3 //to reduce the thinking and make the problem clear, the corner case should be 4 // resolved first. 5 if(target<nums[0]||target>nums[nums.length-1]){ 6 return -1; 7 } 8 int left = 0; 9 int right = nums.length-1; 10 while(left<=right){ 11 int mid = (left+right)/2; 12 if(nums[mid]==target){ 13 if(mid==0||nums[mid-1]!=target) return mid; 14 right = mid-1; 15 }else if(nums[mid]>target){ 16 right = mid-1; 17 }else{ 18 left = mid+1; 19 } 20 } 21 return -1; 22 } 23 private int searchR(int [] nums,int target){ 24 //to reduce the thinking and make the problem clear, the corner case should be 25 // resolved first. 26 if(target<nums[0]||target>nums[nums.length-1]){ 27 return -1; 28 } 29 int left = 0; 30 int right = nums.length-1; 31 while(left<=right){ 32 int mid = (left+right)/2; 33 if(nums[mid]==target){ 34 if(mid==nums.length-1||nums[mid+1]!=target) return mid; 35 left = mid+1; 36 }else if(nums[mid]>target){ 37 right = mid-1; 38 }else{ 39 left = mid+1; 40 } 41 } 42 //when stop the right index must be larger than the right index 43 //the left index can not stop on the index whose value equals target 44 //so we just need to consider right index here 45 return -1; 46 } 47 public int[] searchRange(int[] nums, int target) { 48 int [] res = new int[2]; 49 res [0] = searchL(nums,target); 50 res [1] = searchR(nums,target); 51 return res; 52 } 53 }