C 如何查找数组中大于/小于某个元素的元素数?
我想找到一种最快的方法来查找数组中小于/大于每个元素的元素数 例如:数组是[5,6,8,2,4]。考虑到第一个元素,小于它的元素数为2 我所能做的最好的事情是将每个元素与其余的数组元素进行比较,但对于条目数约为10^5的大型数组,这需要很长时间 我的代码: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]) ) {
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]
iffarr[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;
}