Algorithm 数组中缺少整数

Algorithm 数组中缺少整数,algorithm,Algorithm,给定一个正整数列表,找到不在列表中的最小整数 例如:list=[7,4,9,1],答案是2 计算不在列表中的最小整数的最快算法(无排序)是什么 注意整数列表非常大,因此无法进行哈希运算?O(n*log(n)) 在O(n*log(n))中运行的最简单算法是: 使用O(n*log(n))的快速排序对数组进行排序 遍历数组,找到列表中不存在的最小元素,它是最大的O(n) O(n)和O(1)额外空间 存在一个运行在O(n)中的算法。 其工作原理如下: 遍历数组。对于每个正数i,将数组[i]处的值设

给定一个正整数列表,找到不在列表中的最小整数

例如:list=[7,4,9,1],答案是2

计算不在列表中的最小整数的最快算法(无排序)是什么

注意整数列表非常大,因此无法进行哈希运算?

O(n*log(n))

在O(n*log(n))中运行的最简单算法是:

  • 使用O(n*log(n))的快速排序对数组进行排序
  • 遍历数组,找到列表中不存在的最小元素,它是最大的O(n)
O(n)和O(1)额外空间

存在一个运行在O(n)中的算法。 其工作原理如下:

  • 遍历数组。对于每个正数i,将数组[i]处的值设置为-1。忽略大于数组大小的值
  • 对数组进行第二次迭代,找到第一个非负索引。(O(n))

  • 在一般情况下,我会

  • 对数组进行排序(根据典型数组选择相关排序或使用自适应排序功能)
  • 迭代数组以查找缺少的第一个整数

  • 如果数字唯一,则可以在O(nlogn)中使用二进制搜索。缺少的值最多为n

    • 设置为低=0,高=n
    • 设置a=低+(高-低)/2
    • 低和高之间的计数值小于或等于
      • 如果小于一半,重复high=a
    • 低和高之间的计数值大于a
      • 如果小于一半,则重复low=a
    • 否则没有解决方案(所有值都在数组中)
    //通过使arr[arr[i]-1]为负值,将arr[i]标记为已访问。注意
    //1被减去,因为索引从0开始,正数从1开始
    对于(i=0;i0)
    arr[abs(arr[i])-1]=-arr[abs(arr[i])-1];
    }
    //返回第一个为正的索引值
    对于(i=0;i0)
    返回i+1;//添加1是因为索引从0开始
    }
    
    从阵列中寻找最小正缺失元素的两步算法

  • 我们遍历包含所有正数的数组,为了标记元素x的存在,我们将索引x处的值的符号改为负数。如果x>大小,则忽略x
  • 我们再次遍历数组并打印第一个具有正值的索引。(请记住,当数组从第0个索引开始时,它将是索引+1)
  • 时间:O(n)

    Space:O(1)

    如果您有非常严格的性能要求,那么在迭代之后进行冒泡排序应该足够快。请注意,性能比较可能取决于典型的数组大小和整数值。为什么不排序?您可以就地排序。数组是只读的吗?@dystroy或者如果你正在面试…@dystroy有比O(n*lgn)更好的算法吗?你知道缺少的值吗?如果它们很小(如[0..1000]),那么就很简单。如果正数
    i
    大于数组,那么它就不起作用了?@sp1rs我看不到任何比O(n)更好的方法。因为即使使用散列,您也需要散列每个值(同样是O(n)),并且需要额外的空间(也是O(n))。因此,我不会考虑散列更好。performance@LukasHäfliger我是说你说的方法是一种散列。散列将不起作用。@sp1rs您能澄清您想要的吗?如果您有10^9个数字,此算法将使用4GB内存。你能解释一下为什么散列不起作用吗?此算法将使用大约5*n+n条汇编指令。我不知道你想把代码保存在哪里,我认为O(n)解决方案行不通。假设一个索引为零的数组,如果您有
    [2,3,1]
    呢。如果您开始设置
    array[2]=-1
    ,那么您将丢失
    1
    值,因此您将得出结论,这是不存在的最小值。该数组不应该按此方法排序吗?如果您每次循环整个数组,则不会。这就是为什么它是O(nlogn)而不是O(logn)为什么这比排序和迭代更好?对于O(n)中的算法,请参见我的回答。在最后一种情况下,答案肯定是(列表中的最大值)+1?
    // Mark arr[i] as visited by making arr[arr[i] - 1] negative. Note that 
    // 1 is subtracted because index start from 0 and positive numbers start from 1
    for(i = 0; i < size; i++)
    {
        if(abs(arr[i]) - 1 < size && arr[abs(arr[i]) - 1] > 0)
          arr[abs(arr[i]) - 1] = -arr[abs(arr[i]) - 1];
    }
    
    // Return the first index value at which is positive
    for(i = 0; i < size; i++)
        if (arr[i] > 0)
          return i+1;  // 1 is added becuase indexes start from 0
    }