方法一:从前往后找出第一个出现的target;从后往前找出最后一个出现的target。程序如下
int CountInSorted(int *num, int length, int target);
void main()
{
clock_t ClockBegin = clock();
const int L = 8;
int num[L] = {1,2,3,3,3,3,4,5};
int result = CountInSorted(num, 8, 3);
//int result = NumReversePair(num, 5);
clock_t ClockEnd = clock();
cout << result << endl;
cout << ClockEnd-ClockBegin << "ms" <<endl;
system("pause");
return;
}
int CountInSorted(int *num, int length, int target)
{
if(!num || length < 0)
return -1;
int begin = 0, end = length-1;
while(num[begin]!= target && begin < length) //从前往后扫描
{ ++begin; }
while(num[end]!=target && end >= begin) //从后往前扫描
{ --end; }
return (end >= begin)?(end - begin +1) : -1;
}
**************************************************
方法二:利用二分法,先找出第一个目标值出现的位置,再由此位置往前,往后搜索第一个和最后一个出现位置。
程序如下:
int FindTarget(int *num, int begin, int end, int target);
int CountInSorted(int *num, int length, int target);
int main()
{
clock_t clockbegin,clockend;
clockbegin = clock();
const int L = 8;
int num[L] = {1,2,3,3,3,3,4,5};
int result = CountInSorted(num, 8, 3);
clockend = clock();
cout << clockend-clockbegin << endl;
cout << result << "ms" << endl;
system("pause");
return 0;
}
int FindTarget(int *num, int begin, int end, int target)
{
if(!num ||(end<begin))
return -1;
int mid = begin + ((end-begin)>>1) ;
if(num[mid] == target)
return mid;
else if(num[mid] > target)
return FindTarget(num, begin, mid-1, target);
else
return FindTarget(num, mid+1, end, target);
}
int CountInSorted(int *num, int length, int target)
{
if(!num || length <= 0)
return -1;
//在排序数组中找到一个目标值的位置
int index = FindTarget(num, 0, length-1, target);
//如果能找到一个位置,则再往前,往后寻找第一个和最后一个target位置;
//如果没有找到一个位置,说明数组中没有target,返回-1
if(index<0)
{ return -1;}
else
{
int backward = index-1, forward = index+1;
//找到第一个target
while(num[backward] == target && backward >= 0)
{ --backward; }
++backward;
//找到最后一个target
while(num[forward] == target && forward < length)
{ ++forward; }
--forward;
return (forward - backward + 1);
}
}
*********************************************************
方法三:将二分搜索进行到底,不仅用二分搜索找到“一个”target位置,而且用二分搜索找到第一个和最后一个target位置。(因为看到方法二中的很多计算花在了向前,向后搜索第一个和最后一个target位置,而既然是在sorted中进行搜索,就尝试用二分搜索代替顺序搜索)。
程序如下
int CountInSorted(int *num, int length, int target);
int FindFirstInSorted(int *num, int begin, int end, int target);
int FindLastInSorted(int *num, int begin, int end, int target);
int main()
{
clock_t clockbegin,clockend;
clockbegin = clock();
const int L = 8;
int num[L] = {1,2,3,3,3,3,4,5};
int result = CountInSorted(num, 8, 3);
clockend = clock();
cout << clockend-clockbegin << endl;
cout << result << "ms" << endl;
system("pause");
return 0;
}
int FindFirstInSorted(int *num, int begin, int end, int target)
{
if(!num || end < begin)
return -1;
int mid = begin + ((end-begin)>>1);
//找到一个target位置后不直接返回,而是看前一个是否也为target
if(num[mid] == target)
{
if(mid -1 >=begin && num[mid-1] == target)
{ return FindFirstInSorted(num, begin, mid-1, target); }
else
return mid;
}
else if(num[mid] > target)
return FindFirstInSorted(num, begin, mid-1, target);
else
return FindFirstInSorted(num, mid+1, end, target);
}
int FindLastInSorted(int *num, int begin, int end, int target)
{
if(!num || end < begin)
return -1;
int mid = begin + ((end-begin)>>1);
//找到一个target位置后不直接返回,而是看前一个是否也为target
if(num[mid] == target)
{
if(mid +1 <=end && num[mid+1] == target)
{ return FindLastInSorted(num, mid+1, end, target); }
else
return mid;
}
else if(num[mid] > target)
return FindLastInSorted(num, begin, mid-1, target);
else
return FindLastInSorted(num, mid+1, end, target);
}
int CountInSorted(int *num, int length, int target)
{
//配合二分查找的CountInSorted
if(!num || length <= 0)
return -1;
int first = FindFirstInSorted(num, 0,length-1, target);
int last = FindLastInSorted(num, 0,length-1, target);
return (last-first+1);
}
感受:我去,是不是感觉快了很多呀?应该不会,因为数据量这么小,应该感觉不出什么来的