统计一个数字在排序数组中出现的次数(二分法)

问题:计一个数字在排序数组中出现的次数

如: 整数数组arr,数组中元素的个数是n,数组arr已经排好序,要在arr中找到某个某个整数x出现的次数,比如arr[] = {1,2,2,3,5,10},找到2的出现次数就是2。

问题分析相必看到有序数组的字样,想到利用二分应该是很顺利成章的事了。我们可以利用二分搜索求出x在arr中出现的第一个位置lo和最后一个位置hi,然后计算hi-lo+1的值就是x在arr出现的次数了,当然也有可能x并没有在arr中出现过,这时hi和lo都等于-1。时间复杂度是两个二分的复杂度:2*O(log n)。

/************************************************************************/
/* 10、在排序数组中,找出给定数字出现的次数                                        */
/************************************************************************/
//二分查找,二分查找key第一次出现的位置,二分查找最后一次出现的key
//返回两者相减+1或者找到第一次出现的位置,向后查找
int binarySearchFirstPos(int * iArr, int l, int h, int key)
{
    while(l <= h )
    {
        int mid  = (l + h) / 2;
        if(iArr[mid] < key)
            l = mid +1;
        else if(iArr[mid] > key)
            h = mid - 1;
        else
        {
            if(mid == l || iArr[mid - 1] != key)
                return mid;
            else 
                h = mid - 1;
        }
    }
    return -1;
}
int binarySearchLastPos(int * iArr, int l, int h, int key)
{
    while(l <= h)
    {
        int mid = (l + h) / 2;
        if(iArr[mid] < key)
            l =  mid + 1;
        else if(iArr[mid] > key)
            h = mid - 1;
        else
        {
            if(mid == h || iArr[mid + 1] != key)
                return mid;
            else
                l = mid + 1;
        }
    }
    return -1;
}
int numOfKey(int * iArr, int length, int key)
{
    int firstPos = binarySearchFirstPos(iArr, 0, length - 1, key);
    int lastPos = binarySearchLastPos(iArr, 0, length - 1, key);
    cout << firstPos << "	" << lastPos << endl;;
    if(firstPos == -1)
        return 0;
    else
        return lastPos - firstPos + 1;
}

 可以看以前写的文章二分法的变异,自己写的另外代码:

#include<iostream>
using namespace std;

int searchFirstEqual(int a[],int n,int key)
{
    int low=0,high=n-1,mid;
    while(low<=high)
    {
        mid=(low+high)>>1;
        if(a[mid]>=key)
            high=mid-1;
        else
            low=mid+1;
    }
    if(low<n && a[low]==key) return low;
    else
        return -1;
}

int searchLastEqual(int arr[],int n,int key)
{
    int low=0,high=n-1,mid;
    while(low<=high)
    {
        mid=low+(high-low)/2;
        if(arr[mid]<=key)
        {
            low=mid+1;
        }
        else
        {
            high=mid-1;
        }
    }

    if(high>=0 && arr[high]==key) return high;
    else
        return -1;
}



int main()
{
    int a[]={1,3,3,3,5,6};
    int n=sizeof(a)/sizeof(a[0]);
     
    int start=searchFirstEqual(a,n,3);
    int end=searchLastEqual(a,n,3);

    cout<<start<<endl;
    cout<<end<<endl;
    cout<<end-start+1<<endl;
}
原文地址:https://www.cnblogs.com/youxin/p/3351179.html