我遇到了一个问题,需要程序计算一个间隔内的点数。该问题提供了大量未排序的点,并且lo,hi(restriction lo< = hi),并且其目的是枚举[lo,hi]内的点。问题是虽然我的代码是正确的,但是在给定时间(2200ms)内完成它太耗时。我的代码可以在O(n)中完成这个任务。我想问一下是否有更快的方法。
int n,m,c,lo,hi;
cin>>n>>m;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
cin>>lo>>hi;
c=0;
for(int j=0;j<n;j++){
if(arr[j]<=hi&&lo<=arr[j])c++;
}
cout<<c<<endl;
答案 0 :(得分:3)
在O(n)
时间内解决此问题是不可能的,因为必须至少考虑所有输入一次。
但是,您可以减少n
的常数因子 - 您是否考虑存储一组(start, end)
间隔,而不是简单的数组?什么是输入大小导致这个慢?
编辑经过进一步测试,似乎瓶颈实际上是使用cin
来读取数字。
尝试用cin >> x;
替换scanf("%d", &x);
的每个实例 - 对我来说,这会将运行时间降低到大约0.08秒。
答案 1 :(得分:1)
只有当您需要在同一数据集上多次查找时,才能比O(N)
更快地执行此操作:
对数组或其副本进行排序。对于查找,您可以使用二进制搜索 - 即O(log 2 N)复合体。
使用像二叉树这样的平面数组,查找复杂性将与#1相同。
答案 2 :(得分:0)
我尝试将此作为评论发布,因为我刚刚重新编写代码并且C ++是很久以前的事了,但我还没有成为这个社区的一员,足以发表评论。
在我看来,您提供的代码片段中唯一可管理的瓶颈是您循环一次以创建数组然后再次循环以检查值。是不是只能执行一次循环?你读的时候检查一下吗?老实说,我不记得cin和cout很好;我认为它们是高度优化的读写设施。但是,对于使用效率较低的读/写并在一个循环内即时执行计算的设置来测试您的设置可能是值得的。
再次,很抱歉将此作为答案发布,因为我实际上没有回答这个问题。很高兴被允许做一个试用评论或类似的事情。
如果这个“答案”被低估或删除,或者其他什么,我将不会被冒犯。