版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
统计一个数字在排序数组中出现的次数。
直接
遍历数组统计出现次数 O(n)
二分搜索找到一个数,然后再分别前后扫描O(n)
更好的用二分查找
二分查找直接找到第一个k和最后一个k?? O(logn)
一、.找第一个k
先看数组中间,mid>k,下次在数组前半段找
mid《k,在后半段找就可以了
如果mid=k,先判断是不是第一个k,
1.如果中间数的前一个也是k,那么第一个k在前半段找
2.如果不是k了,那mid就是第一个k
二、找第二个k
类上
三、
函数中写:
public int GetNumberOfK(int [] array , int k) {
int number=0;
if(array.length==0||array==null){
return 0;
}
int first=getFirstK(array,k,0,array.length-1);
int last=getLastK(array,k,0,array.length-1);
if(first!=-1&&last!=-1){
number=last-first+1;
}
return number;
}
递归写二分查找
一、.找第一个k
先看数组中间,mid>k,下次在数组前半段找
mid《k,在后半段找就可以了
如果mid=k,先判断是不是第一个k,
1.如果中间数的前一个也是k,那么第一个k在前半段找
2.如果不是k了,那mid就是第一个k
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int number=0;
if(array.length==0||array==null){
return 0;
}
int first=getFirstK(array,k,0,array.length-1);
int last=getLastK(array,k,0,array.length-1);
if(first!=-1&&last!=-1){ //必要判断
number=last-first+1;
}
return number;
}
public int getFirstK(int[] array,int k,int start,int end){
if(start>end) //必要判断
return -1;
int mid=start+(end-start)/2;
if(array[mid]<k)
return getFirstK(array,k,mid+1,end);
else if(array[mid]>k)
return getFirstK(array,k,start,mid-1);
else if(mid-1>=0&&array[mid-1]==k) //mid-1大于也要等于
return getFirstK(array,k,start,mid-1);
else
return mid;
}
public int getLastK(int[] array,int k,int start,int end){
if(start>end)
return -1;
int mid=start+(end-start)/2;
if(array[mid]<k)
return getLastK(array,k,mid+1,end);
else if(array[mid]>k)
return getLastK(array,k,start,mid-1);
else if(mid+1<array.length&&array[mid+1]==k)
return getLastK(array,k,mid+1,end);
else
return mid;
}
}
循环写二分查找
public int getFirstK(int[] array,int k,int start,int end){
int mid=(start+end)>>1;
while(start<=end){
if(array[mid]<k)
start=mid+1;
else if(array[mid]>k)
end=mid-1;
else if(mid-1>=0&&array[mid-1]==k)
end=mid-1;
else
return mid;
mid=(start+end)>>1;
}
return -1;
}
public int getLastK(int[] array,int k,int start,int end){
int mid=(start+end)>>1;
while(start<=end){
if(array[mid]<k)
start=mid+1;
else if(array[mid]>k)
end=mid-1;
else if(mid+1<array.length&&array[mid+1]==k)
start=mid+1;
else
return mid;
mid=(start+end)>>1;
}
return -1;
}