【发布时间】:2019-06-05 00:59:14
【问题描述】:
我需要降低代码的时间复杂度,到目前为止,我尝试对其进行预排序并使用二进制搜索来查找所需元素的索引,并使用索引来查找键号之前的多少个元素,但我可以' t 通过,因为我的代码很慢。有没有其他方法可以让这段代码更快?
重要细节:
- 我需要使用一个大数组和多个查询(数组保持不变)运行这段代码,最多 100k。
- 每个元素的值最多为 10 亿。
- 这个问题的时间限制是0.1s
例子:
假设我有一个包含 15 个元素的数组,我有 5 个查询要做。
数组:1002 19 3 8 22 123 14 5234 123 657 41 829 34 2314 15
查询:100 1000 78 3 1
输出:8 12 8 1 0
我尝试对它进行预排序并使用二进制搜索,但仍然无法通过 0,1s 的时间限制。
#include<stdio.h>
void swap(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
int partition(int a[],int p,int r){
int temp, i,x;
x=a[r];
i=p-1;
for(int j=p;j<=r;j++){
if(a[j]<x){
i++;
swap(&a[i],&a[j]);
}
}
i++;
swap(&a[i],&a[r]);;
return i;
}
void qsort(int a[],int p,int r){
int q;
if(p<r){
q=partition(a,p,r);
qsort(a,p,q-1);
qsort(a,q+1,r);
}
}
int binarySearch(int arr[], int n, int key){
int left = 0, right = n;
int mid;
while (left < right){
mid = left + (right-left)/2;
if (arr[mid] == key){
while (arr[mid+1] == key && mid+1<n)
mid++;
break;
}else if (arr[mid] > key)
right = mid;
else
left = mid + 1;
}
while (arr[mid] > key)
mid--;
return mid + 1;
}
int main(){
int a, b;
scanf("%d %d",&a, &b);
int data[a],d;
for(int i=0;i<a;i++){
scanf("%d", &data[i]);
}
qsort(c, 0, a-1);
for(int i=0;i<b;i++){
scanf("%d", &d);
printf("%d\n", binarySearch(c, a, d));
}
return 0;
}
【问题讨论】:
-
您可以使用 stdlib 中已经定义的 qsort,如果您可以使用 c++,您可以使用 sort 和 lower_bound/upper_bound 函数来替换 qsort 和二分查找。
-
这里有一个错误:
while (arr[mid+1] == key && mid+1<n)。您需要确保索引检查发生在项目检查之前。如果您在进行边界检查之前访问arr[mid+1],您可能会遇到访问冲突。 -
看起来也像
with (arr[mid] > key)中的一个错误。如果key小于数组中的任何项目,这看起来mid可能会变为负数。