zoukankan      html  css  js  c++  java
  • 统计一个数字在排序数组中出现的次数(二分法)

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

    如: 整数数组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;
    }
  • 相关阅读:
    React使用iconfont图标下载到本地symbol引用
    【汇编】求100以内的素数asm
    jQuery Ajax.BeginForm方法回调函数高版本3.3.1不兼容问题
    python中的深拷贝与浅拷贝
    闲来无事做个C#小项目——2
    C#使用MD5加密
    数据结构部分总结(c语言版)
    vue 上传视频和图片 并且截取视频第一帧作为播放前默认图片
    vue el-cascader取id和lable的值
    C# 枚举的定义,枚举的用法,获取枚举值
  • 原文地址:https://www.cnblogs.com/youxin/p/3351179.html
Copyright © 2011-2022 走看看