您的位置:首页 > Web前端

剑指offer-数字在排序数组中出现的次数

2016-07-02 12:10 417 查看

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

统计一个数字在排序数组中出现的次数。

很明显,对于语序有序数组而言,二分查找再适合不过了

普通的二分查找

二分查找到元素对应的索引,然后向前、向后遍历查找计数

package com.genge.offer;

/**
* Created by Genge on 2016-07-02.
* 统计一个数字在排序数组中出现的次数。
*/
public class GetNumberOfK {
public int GetNumberOfK(int [] array , int k) {
if (array == null || array.length <= 0) {
return 0;
}
int index = binarySearch(array, 0, array.length - 1, k);
int pre = index-1,next = index+1;
int count = 0;
if (array[index] == k) {
count++;
} else {
return 0;
}
while (pre >= 0) {
if (array[pre] == k) {
count++;
}
pre--;
}
while (next < array.length) {
if (array[next] == k) {
count++;
}
next++;
}
return count;
}

int binarySearch(int[] array, int low, int high, int k) {
int mid = (low + high) >> 1;
if (low < high) {
if (k > array[mid]) {
low = mid + 1;
} else if (k < array[mid]) {
high = mid - 1;
} else {
return mid;
}
}
if (low >= high) {
return -1;
}
return binarySearch(array, low, high, k);
}
}


优化二分查找计数

对于有序数组二分查找无疑是最快的,但是查找后还要遍历(方法一),感觉格格不入,拖慢了速度。其实仔细想想,我们可以求得第一个K 的索引和 最后一个K 的索引,然后二者位置相减,就得到个数了

不多说,自己体会咯:

class Solution {
/*二分查找 找到第一个K 和 最后一个K 二者位置相减*/
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.empty())
return 0;
int number = 0;
int first = GetFirstIndex(data,k,0,data.size()-1);
int last = GetLastIndex(data,k,0,data.size()-1);
if(first>-1 && last>-1)
number = last - first +1;
return number;

}
int GetFirstIndex(vector<int> &data,int k,int start,int end){
if(start > end)
return -1;
int mid = (start+end)/2;
if(data[mid] == k){
if((mid > 0 && data[mid-1] != k) || mid == 0)
return mid;
else
end = mid-1;
}
else{
if(mid > k)
end = mid - 1;
else
start = mid + 1;
}
return GetFirstIndex(data,k,start,end);
}
int GetLastIndex(vector<int> &data,int k,int start,int end){
if(start > end)
return -1;
int mid = (start+end)/2;
if(data[mid]==k){
if((mid>0 && data[mid+1] !=k) || mid == end)
return mid;
else
start = mid +1;
}
else{
if(mid>k)
end = mid-1;
else
start = mid+1;
}
return GetLastIndex(data,k,start,end);
}
};


第二种方法是总结别人的算法,感兴趣的可以自己用java再重写一次,个人感觉没必要,大同小异
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分查找 索引 遍历