C 阵列验证-不使用辅助阵列

C 阵列验证-不使用辅助阵列,c,arrays,logic,memory-efficient,C,Arrays,Logic,Memory Efficient,这个问题是针对真正的脑力劳动者的,因为它应该在没有辅助阵列的情况下完成 而且必须是最有效的 C程序-需要接收带有X个数字的数组 (假设X=4数组:5,4,3,2) 并检查数组是否包含从0到X-1的所有数字 (如果X为44,则需要检查数组中是否存在0到43之间的所有数字) 它必须是超级高效的-我的意思是,在阵列上运行43次不是一个选项 你知道怎么做吗??我花了好几个小时都在想这个问题,但没有成功 它必须是O(n)。您可以对数组进行排序,然后扫描一次。这将为您提供O(N logn)性能,比使用简单方

这个问题是针对真正的脑力劳动者的,因为它应该在没有辅助阵列的情况下完成 而且必须是最有效的

C程序-需要接收带有X个数字的数组 (假设X=4数组:5,4,3,2) 并检查数组是否包含从0到X-1的所有数字 (如果X为44,则需要检查数组中是否存在0到43之间的所有数字)

它必须是超级高效的-我的意思是,在阵列上运行43次不是一个选项

你知道怎么做吗??我花了好几个小时都在想这个问题,但没有成功


它必须是O(n)。

您可以对数组进行排序,然后扫描一次。这将为您提供O(N logn)性能,比使用简单方法所需的O(N^2)性能更好。

您可以将问题简化为查找重复项

证明:

  • 如果数组的长度不是X=>则缺少数字。您可以在O(1)或O(n)中轻松地检查这一点
  • Else=>您要么拥有所有正确的数字,要么存在重复的数字
这样,您就可以使用以下实现:。还要确保检查数组的边界。如果数字不在边界内,则数组包含不正确的数字


这导致了一个O(n)解决方案。

我不明白我在这个问题中遗漏了什么,但我不明白为什么任何(合理的)解决方案都应该比
O(n)
时间(和空间)复杂度更高/更差

从上述评论和回答中,我了解到:

  • 负数:我不确定是否允许负数。OP显示
    检查所有数组是否具有从0到X-1的所有数字
    。因此,数组中不应出现小于
    0
    的任何内容。所以我假设负数是不允许的
  • 重复数字:参考OP中的同一引用-
    检查是否所有数组都有从0到X-1的所有数字
    我猜如果
    X
    是数组的大小,并且从
    0到
    X-1的所有数字都应该存在,我猜不允许重复数字

因此,在进行上述假设时,我们可以使用一个位来检查
i
0阅读此内容以获得答案-

由n个元素组成的数组,其中包含从0到n-1的元素,这些数字中的任何一个出现任意次数

例如,设n为7,数组为{1,2,3,4,5,4,6},则答案应为FALSE


<> P>是否上述的语句与自己矛盾?!

< P>参见一些精彩的答案,C++的实现可以是@ CAF的答案。
bool-stop=true;
//首先将元素i放置在位置A[i],即4放置在位置A[4]

for(int  i = 0; i<n; i++) {
    while (A[A[i]] != A[i]){ 
        swap(A[i], A[A[i]])
    }
}
// than u can have the second loop which does the decision 
for(int  i = 0; i<n && !stop; i++) {
    if (A[i] != i){ 
        stop = true;
    }
}

if (stop)
    printf("duplicate");
else
   printf("not duplicate)

for(int i=0;i如果允许更改数组的顺序,您可以使用就地排序算法,然后检查是否存在某些i:

array[i] == array[i+1]
时间复杂度可以是O(n*lg n)。

O(n)解决方案:算法试图通过与占据原点位置的元素交换,将数组中的每个元素置于其正确位置,例如1置于[0],2置于[1]

首先,i=1,a[i-1]=1,没关系,什么都不会碰

i = 1
a = 1 6 3 4 5 7 1 
然后,i=2,a[i-1]=6!=2,然后交换a[i-1]和a[6-1]

i = 2 
a = 1 7 3 4 5 6 1
然后,我仍然是2,但是a[i-1]==7!=2,然后交换a[i-1]和a[7-1]

i = 2
a = 1 1 3 4 5 6 7
现在i=2,但我们看到a[i-1]==a[1-1],因此我们找到了重复项

完整资料来源:

#include <stdio.h>

int main() {
    int a[7] = {1, 6, 3, 4, 5, 7, 1};
    int i, t;
    for (i = 0; i < 7; ++i) {
        while (a[i] != i + 1) {
            if (a[i] == a[a[i] - 1]) {
                printf("duplicate: %d\n", a[i]);
                goto out;
            } 
            t = a[i];
            a[i] = a[a[i] - 1];
            a[t - 1] = t;
        }
    }
    printf("no duplicate\n");
out:
    return 0;
}
#包括
int main(){
inta[7]={1,6,3,4,5,7,1};
int i,t;
对于(i=0;i<7;++i){
while(a[i]!=i+1){
如果(a[i]==a[a[i]-1]){
printf(“副本:%d\n”,a[i]);
出去;
} 
t=a[i];
a[i]=a[a[i]-1];
a[t-1]=t;
}
}
printf(“无重复\n”);
输出:
返回0;
}

如果两个数组都已排序,则可以使用修改后的合并操作(如mergesort中使用的操作)。

对两个数组进行排序(在
O(n log n)
中)。然后将两个数组视为队列:

  • 如果两个队列的头元素相等,则打印其中一个并同时弹出
  • 如果头部元素不相等,则弹出较小的元素
  • 重复一遍

  • 您可以[在平均情况下]比建议的
    O(nlogn)
    解决方案做得更好。
    有一个
    O(n)
    使用哈希表的铠装平均案例解决方案:

    hash <- new hash set
    for each e in A:
      hash.add(e)
    for each e in B:
      if hash.contains(e): print e
    

    hash对较小的元素进行排序,并使用二进制搜索在较大的元素中搜索每个元素。这样,您可以在
    O((n1+n2)*log(n1))
    中执行此操作,其中
    n1,n2
    是数组的大小(
    n1
    是较小的)。

    您需要另外一个步骤:检查是否没有
    i
    ,以便
    array[i]>=X | | array[i]<0
    。有一节描述整数排序。您只需要名称?不想实现它吗?它是家庭作业吗?:)我猜bucket sort做的事情非常类似。允许重复,但如果有重复,这意味着函数将被错误地执行,这比排序和检查是否所有数字都在里面好吗?givven数组x将始终包含0到x之间的数字-1@Sveta26排序在这里没有帮助..任何排序都必须进行扫描整个数组一次。因此,最小时间(或最佳时间复杂度)为O(n)。@duedl0r我已经在程序注释中提到了这一点,作为警告-
    /*如果X大于sizeof(int)然后将标记类型更改为更宽的标记类型!*/
    。OTOH我不会给出100%的答案,因为我希望原始作者学习并理解
    C
    。请重新考虑-1?!givven数组x将始终包含0到x-1之间的数字-在您之前的回答中,您将数组视为可以有更大的数字比x-1…但是我需要的函数总是有一个包含x元素的数组,并且没有任何allemnt会超过x-1Why-1而没有解释?!它必须
    #include <stdio.h>
    
    int main() {
        int a[7] = {1, 6, 3, 4, 5, 7, 1};
        int i, t;
        for (i = 0; i < 7; ++i) {
            while (a[i] != i + 1) {
                if (a[i] == a[a[i] - 1]) {
                    printf("duplicate: %d\n", a[i]);
                    goto out;
                } 
                t = a[i];
                a[i] = a[a[i] - 1];
                a[t - 1] = t;
            }
        }
        printf("no duplicate\n");
    out:
        return 0;
    }
    
    hash <- new hash set
    for each e in A:
      hash.add(e)
    for each e in B:
      if hash.contains(e): print e