C 如何查找数组中大于/小于某个元素的元素数?

C 如何查找数组中大于/小于某个元素的元素数?,c,arrays,algorithm,performance,search,C,Arrays,Algorithm,Performance,Search,我想找到一种最快的方法来查找数组中小于/大于每个元素的元素数 例如:数组是[5,6,8,2,4]。考虑到第一个元素,小于它的元素数为2 我所能做的最好的事情是将每个元素与其余的数组元素进行比较,但对于条目数约为10^5的大型数组,这需要很长时间 我的代码: for(i=0;i<n;i++) { count=0; for(j=0;j<n;j++) { if( i!=j && (ar[i]>ar[j]) ) {

我想找到一种最快的方法来查找数组中小于/大于每个元素的元素数

例如:数组是[5,6,8,2,4]。考虑到第一个元素,小于它的元素数为2

我所能做的最好的事情是将每个元素与其余的数组元素进行比较,但对于条目数约为10^5的大型数组,这需要很长时间

我的代码:

for(i=0;i<n;i++)
{
    count=0;
    for(j=0;j<n;j++)
    {
        if( i!=j && (ar[i]>ar[j]) )
        {
            count++;
        }
    }
    printf("%lld ",count);
}

对于(i=0;i一个简单的方法是:

  • 首先对数组排序,可能使用
  • 对已排序的数组执行一次排序
  • 根据阵列的大小,从所需元素计算其余元素

  • 如果您计划执行单个类似查询,则无法改进您已经提出的线性方法。但是,如果您计划执行许多类似查询,则可以对数组进行排序,然后对每个查询执行二进制搜索。这将导致
    O(n*log(n))
    预计算复杂性和
    O(log(n))
    每个查询的复杂性。请注意,如果您计划执行的查询超过了
    O(log(n))

    ,则此方法只能是一种改进,正如其他人所说,您可以在O(nlogn)中解决它通过对数组排序,然后为每个元素
    x
    查找低于/高于
    x
    的第一个数字的索引

    我想证明问题的下界:
    在代数树模型下(基本上意味着没有散列),它做得比ω(nlogn)更好

    证明:我们将通过减少成本来证明这一点。
    假设我们有一个算法
    A
    ,它在
    O(f(n))

    给定一个数组
    arr
    ,在数组上调用
    A
    。结果是一个新数组
    res
    ,其中
    res[i]
    是小于
    arr[i]
    的元素数。
    请注意,对于任何两个索引
    i,j
    res[i]==res[j]
    iff
    arr[i]==arr[j]

    如果
    res
    中存在重复项,则
    arr
    中存在重复项。
    但是,
    res
    中的所有元素都在范围
    [0,n-1]
    内。这意味着我们存在一个元素区分问题,其中所有元素都以
    n
    为边界。
    此变体可在
    O(n)
    中使用桶排序的修改来解决

    因此,我们基本上展示了一个算法来解决
    O(n+f(n))
    中的问题(元素区分度),但由于元素区分度是
    Omega(nlogn)
    问题,在这个模型下,这意味着
    f(n)
    本身必须在
    Omega(nlogn)


    QED

    最简单的技巧是先对数组排序,然后计算数组中的元素数。例如,如果有10个元素,那么第一个元素小于9,第二个元素也小于8,依此类推

    唯一的例外是,如果你有两个相同的项目,你只需要比较两个项目,第一个和下一个。我认为这是最可行的解决方案。

    对数组排序。 现在,对于每个查询,您可以将O(logn)时间减少到O(1)时间。 创建一个HashMap.Loop遍历排序数组的每个元素,并用元素作为键和排序位置作为值填充HashMap。
    HashMap提供了O(1)查找,因此对于每个查询,它比二进制搜索更具时间效率。

    以下代码片段将帮助您进行查询。
    它是使用二进制搜索实现的,因此这可以通过记录(n)时间复杂度来实现,其中n是数组中的元素数。

    请注意,您需要先对数组进行排序。

    因此总体时间复杂度为n*log(n

    #包括
    使用名称空间std;
    int-binarysearchlargerelements(int-arr[],int-val){
    int l=0;
    int size=sizeof(arr)/sizeof(arr[0]);
    int r=尺寸-1;
    int resultantIndex=大小;
    
    虽然(l最好的方法是使用Fenwick树/二元索引树……这些数据结构是专门为此类问题设计的。请查看它们,谷歌搜索或观看视频bcoz无法通过键入来解释…

    首先复制数组,否则无法给出所需的答案。并考虑到数组元素可以e通过修改二进制搜索使最后一个元素的索引等于x而等于。否则,如果所有元素只有一个或两个不同的值,则返回到二次时间。@gnasher729感谢您的详细说明。对,确实如此。:-)如何修改二进制搜索以考虑数组中的重复值。@SwapnilPandey,对不起,排序时不注意这一点吗?我的意思是重复值的处理将按照排序算法进行定义。@IvayloStrandjev它不能比Omega(nlogn)做得更好在代数树模型下。其中“它”是问题的要求:得到
    res[i]=低于arr[i]
    @IvayloStrandjev的元素数的数组。不,简单的方法是二次的。问题要求得到所有
    x
    @IvayloStrandjev的
    x
    的元素数,这从来都不是,但是。。。(问题的第一行和算法都澄清了它适用于所有元素,并且从未被编辑过)@IvayloStrandjev问题陈述中发生的变化在编辑部分。没有其他变化:)你的问题是这样的,如果你想要准确的答案,你必须遍历整个清单(因为你不知道下一个元素是什么)或者对它进行排序,或者使用其他启发式方法,粗略估计下一个元素可能是什么。检查这个。它会帮助你。
    #include<bits/stdc++.h>
    using namespace std;
    
    int binarySearchLargerElenents(int arr[], int val){
        int l = 0;
        int size = sizeof(arr)/sizeof(arr[0]);
        int r = size-1;
        int resultantIndex = size;
        while(l<=r){
            int mid = l + (r-l) / 2;
            if(arr[mid] <= val){
                l = mid +1;
            }
            else{
                r = mid -1;
                resultantIndex = mid;
            }
        }
        return (size-resultantIndex);
    }
    
    int binarySearchSmallerElements(int arr[], int val){
        int l = 0;
        int size = sizeof(arr)/sizeof(arr[0]);
        int r = size-1;
        int resultantIndex = size;
        // strictly less than val.
        // while(l<=r){
        //   int mid = l + (r - l) / 2;
        //   if(arr[mid] < val){
        //     l = mid + 1;
        //
        //   }
        //   else{
        //     r = mid - 1;
        //     resultantIndex = mid;
        //   }
        // }
    
        // less that or equal to val
        while(l<=r){
            int mid = l + (r-l) / 2;
            if(arr[mid] <= val){
                l = mid +1;
            }
            else{
                r = mid-1;
                resultantIndex = mid;
            }
        }
        return resultantIndex;
    }
    int main(){
        int arr[] = {1, 2, 3, 4, 5, 5, 7};
        int x;
        cout<<"Input x: ";
        cin>>x;
        int countOfSmallerElements = binarySearchSmallerElements(arr, x);
        int countOfLargerElements = binarySearchLargerElenents(arr, x);
    
        cout<<" smaller than "<<x <<" : "<< countOfSmallerElements<<endl;
        cout<<" larger than "<<x <<" : "<< countOfLargerElements<<endl;
    }