如何创建一个从1开始到n结尾的数字数组,而不包括数组中给定的k个数字?例如,n = 10 k = 2,k的两个数字是3和6,那么我的数组是1,2,4,5,7,8,9,10。
我必须为像
这样的大数字做这件事1< n< 10 ^ 9
然后
0< k<分(10 ^ 5,n)的
对于较小的数字,我尝试索引,然后将其存储在一个不同的数组中,占用了大量的空间和时间。我怎样才能有效地完成它?
scanf("%lld%lld",&n,&k);
f=0;
long long int a[100010]={0};
long long int b[100010]={0};
for(i=0;i<k;i++)
{
scanf("%lld",&temp);
a[temp]=-1;
}
for(i=0;i<n+1;i++)
{
if(a[i]!=-1)
{
b[f++]=i;
}
}
答案 0 :(得分:0)
使用n
作为范围的结尾,k
作为跳过的数字的数量,narr
作为保存结果的数组,karr
作为数组保持要跳过的数字:karr
只需要k
个元素。如果对karr
进行了排序,则只需将每个新号码与karr
中的一个元素进行比较,然后在匹配时移至下一个karr
,并将新号码添加到narr
他们什么时候没有。以下示例显示了这一点(但没有错误检查):
#include <stdlib.h> // for malloc and qsort
#include <stdio.h> // for printf
// compare function for qsort
static int llcompare(const void *a, const void *b)
{
if (*(long long *)a > *(long long *)b) return 1;
if (*(long long *)b < *(long long *)b) return -1;
return 0;
}
int main()
{
long long n = 0, k = 0;
scanf("%lld%lld",&n,&k); // get n and k, as in your code
// allocate arrays: k elements for karr, and (n - k) for results in narr
long long *karr = malloc(sizeof(long long) * k);
long long *narr = malloc(sizeof(long long) * (n - k));
// read numbers to skip into karr
for (int i = 0; i < k; i++) {
scanf("%lld", &karr[i]);
}
// sort karr ascending
qsort(karr,k,sizeof(long long),llcompare);
// using pointers to move through narr and karr
long long *pn = narr; // element of narr to set
long long *pk = karr; // element of karr to compare against
// pkend marks the end of karr, to check when we've passed the last omitted
// number
long long *pkend = karr + k;
// loop over the needed range
for (long long i = 1; i <= n; i++) {
if (pk != pkend && i == *pk) {
// if i is the next number to omit, move pk to the next omitted
// number (without adding i to results)
pk++;
} else {
// otherwise, add i to results then move pn to the next element
*(pn++) = i;
}
}
// print results from narr
for (long long i = 0; i < (n - k); i++)
printf("%lld ", narr[i]);
printf("\n");
// free karr and narr when done
free(karr);
free(narr);
return 0;
}
不需要庞大的查找表,并且因为添加到结果中的数字只会增加,所以要跳过的下一个数字将始终是karr
中没有数字的最低数字。已经到达...所以只需要为每个新号码检查karr
中的一个元素。
上面的代码还假设karr
中没有数字未在循环中检查,即karr
中没有数字超出范围1..N。并且由于缺少错误检查/处理,如果您输入无效输入或malloc()
由于某种原因失败,则可能表现不佳。