剑指Offer37:数字在排序数组中出现的次数(Java)
参考chaibubble的博客:https://blog.csdn.net/chaipp0607/article/details/76977687
思路分析:
排序数组:已经排好序的数组。(一开始不懂是什么意思..)
- 可以遍历整个数组计算k值有多少个,这最容易想到,时间复杂度O(n)。
- 利用二分查找方法找到最左端k值坐标L与最右端k值坐标R,R-L+1就是k值的个数。
题目没有说数组顺序是由大到小还是由小到大,自己可以加判断分析,实际牛客在线编程默认的是由小到大,不考虑由大到小的顺序没问题。
考察:二分查找
题目描述:
统计一个数字在排序数组中出现的次数。
Java代码:
public class Solution {
public int GetNumberOfK(int [] array , int k) {
//排序数组:排好序的数组
int sum=0;
int l=leftk(array,k,0,array.length-1);
int r=rightk(array,k,0,array.length-1);
if(l>-1&&r>-1){
sum= r-l+1;
}
return sum;
}
public static int leftk(int []arr,int k,int left,int right){
if(left>right){
return -1;
}
int middle=(right+left)/2;
if(arr[middle]==k){
if(middle!=left&&arr[middle-1]!=k||middle==left){
return middle;
}
else right=middle-1;
}
else if(arr[0]<=arr[arr.length-1]){
if(arr[middle]>k){
right=middle-1;
}
else if(arr[middle]<k){
left=middle+1;
}
}
else if(arr[0]>arr[arr.length-1]){//假设当时排序数组是由大到小的,不写也可以的
if(arr[middle]>k){
left=middle-1;
}
else if(arr[middle]<k){
right=middle+1;
}
}
return leftk(arr,k,left,right);
}
public static int rightk(int []arr,int k,int left,int right){
if(left>right){
return -1;
}
int middle=(right+left)/2;
if (arr[middle]==k){
if(middle!=right&&arr[middle+1]!=k||middle==right){
return middle;
}
else{
left=middle+1;
}
}
else if(arr[0]<=arr[arr.length-1]){
if(arr[middle]>k){
right=middle-1;
}
else {
left=middle+1;
}
}
else if(arr[0]>arr[arr.length-1]){//假设当时排序数组是由大到小的,不写也可以的
if(arr[middle]>k){
left=middle+1;
}
else{
right=middle-1;
}
}
return rightk(arr,k,left,right);
}
}