问题说明:
1.给定排序的数组,例如从小到大已经排序。
2.给定某个查找关键字,求出该关键字出现的次数。
3.完全遍历一遍,时间复杂度为O(n),并未充分利用排序的信息。
4.需要借鉴二分查找的思想改进,算法的时间复杂度为O(logn)。
package com.zhang.csdn;
/**
* @author pizi
* @date 2014年1月7日
*/
public class BinarySearchTest {
/**@author pizi
* @param @param args
* @return void
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//int[] a = {1};
//int[] a = {1,2};
//int[] a = {1,2,3};
int[] a = {2,4,5,7,11,11,15,16,16,16,17,18,19,19};
System.out.println(countValue(a, 19));
}
// find the count of keyValue in sorted array
// not find return - 1
public static int countValue(int[] sorted, int keyValue){
int len = 0;
if(sorted == null ||(len = sorted.length) == 0){
throw new IllegalArgumentException();
}
int firstPos = getFirstKey(sorted, 0, len - 1, keyValue);
int lastPos = getLastKey(sorted, 0, len - 1, keyValue);
boolean isFound = (firstPos != -1) && (lastPos != -1);
return isFound? (lastPos - firstPos + 1) : -1;
}
private static int getLastKey(int[] sorted, int fromIndex, int toIndex, int keyValue){
if(fromIndex > toIndex){
return -1;
}
// fromIndex <= toIndex
int midIndex = (fromIndex + toIndex) >> 1;
int midValue = sorted[midIndex];
if(midValue < keyValue){
return getLastKey(sorted, midIndex + 1, toIndex, keyValue);
}
if(midValue > keyValue){
return getLastKey(sorted, fromIndex, midIndex - 1, keyValue);
}
//midValue == keyValue
boolean isLast = (midIndex == toIndex) ||((midIndex < toIndex) && (sorted[midIndex + 1] != keyValue));
return isLast? midIndex : getLastKey(sorted, midIndex + 1, toIndex, keyValue);
}
private static int getFirstKey(int[] sorted,int fromIndex, int toIndex, int keyValue){
if(fromIndex > toIndex){
return -1;
}
// fromIndex <= toIndex
int midIndex = (fromIndex + toIndex) >> 1;
int midValue = sorted[midIndex];
if(midValue < keyValue){
return getFirstKey(sorted, midIndex + 1, toIndex, keyValue);
}
if(midValue > keyValue){
return getFirstKey(sorted, fromIndex, midIndex - 1, keyValue);
}
// midValue == keyValue
boolean isFirst = (midIndex == fromIndex) || ((midIndex > fromIndex) && (sorted[midIndex - 1] != keyValue));
return isFirst? midIndex : getFirstKey(sorted, fromIndex, midIndex - 1, keyValue);
}
}