缺少数字

问题描述

| 给定大小为n的数组。它包含1到n范围内的数字。每个数字都在 除2个数字外,至少一次。查找丢失的数字。 例如。大小为5的数组 元素假定为3,1,4,3 一种方法
static int k;
for(i=1;i<=n;i++)
{
  for(j=0;j<n;j++)
  {
    if(i==a[j])
      break;
   }
    if(j==n)
    {
      k++;
      printf(\"missing element is\",a[j]);
    }

  if(k==2)
    break;}
一个解决方案可以.. 对于(i = 0; i     

解决方法

使用ѭ1排序数组,然后在其上循环一次以查找丢失的值。由于排序的原因,平均O(n * log(n))时间以及最少的恒定额外存储量。     ,首先让我解释一下这个概念: 你知道自然数之和1 .... n是 (n *(n + 1))/ 2。也知道前n个自然数1,2,...的平方和是n *(n + 1)*(2n + 1)/ 6因此,您可以使用上述概念在O(n)时间内解决上述问题。 同样,如果对空间复杂度的考虑不多,则可以使用基于计数的方法,这需要O(n)的时间和空间复杂度。 有关更详细的解决方案,请访问在给定数组中查找两个重复元素     ,我喜欢Algorithmist链接中的“将数组元素用作索引”方法。   方法5(使用数组元素作为索引)   感谢Manish K. Aasawat提出了此方法。
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
   make it negative by   A[abs(A[i])]=-A[abs(A[i])];
else  // i.e.,A[abs(A[i])] is negative
   this   element (ith element of list) is a repetition
}
唯一的区别是,这里将遍历1到n。 请注意,这是一个不占用额外空间的单遍解决方案(除了存储
i
)! 脚注: 从技术上讲,它“窃取”了一些额外空间-本质上是计数器数组解决方案,但是它没有分配自己的整数数组,而是使用原始数组的符号位作为计数器。     ,我没有检查或运行此代码,但是您应该明白这一点。
int print_missing(int *arr,size_t length) {
  int *new_arr = calloc(sizeof(int) * length);
  int i;
  for(i = 0; i < length; i++) {
    new_arr[arr[i]] = 1;
  }
  for(i = 0; i < length; i++) {
    if(!new_arr[i]) {
      printf(\"Number %i is missing\\n\",i);
    }
  }
  free(new_arr);
  return 0;
}
运行时应为O(2n)。如果我错了纠正我。     ,目前尚不清楚为什么天真的方法(您可以使用位域或数组)来标记您所看到的项目并不只是很好。 O(2n)CPU,O(n / 8)存储。     ,如果您可以自由选择语言,请使用python \'s set。
numbers = [3,1,4,3]
print set (range (1,len (numbers) + 1) ) - set (numbers)
产生输出
set([2,5])
    ,干得好。 C#解决方案:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
  HashSet<int> values = new HashSet<int>( numbers ) ;

  for( int value = 1 ; value <= numbers.Length ; ++value )
  {
    if ( !values.Contains(value) ) yield return value ;
  }
}
    ,我发现您的代码存在许多问题。首先,
j==n
永远不会发生,这不会给我们遗漏的号码。尝试将initialize9ѭ初始化为0之前,还应将其初始化为0。我写了一个与您相似的算法,但是可以正常工作。但是,它并没有比您期望的更快:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3,3 };

for(int i = 1; i <= n; i++)
{
  for(int j = 0; j < n; j++)
  {
    if(a[j] == i)
    {
        found = true;
        break;
    }
  }
  if(!found)
  {
      printf(\"missing element is %d\\n\",i);
      k++;
      if(k==2)
        break;
  }
  else
      found = false;
}
H2H     ,使用支持数组可以归档O(n)
int support[n];

// this loop here fills the support array with the
// number of a[i]\'s occurences
for(int i = 0; i < n; i++)
    support[a[i]] += 1; 

// now look which are missing (or duplicates,or whatever)
for(int i = 0; i < n; i++)
    if(support[i] == 0) printf(\"%d is missing\",i);
    ,**
 for(i=0; i < n;i++) 
{   

while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{

swap(a[i],a[a[i]-1]); 
} 

for(i=0;i< n;i++) 
{ 
if(a[i]!=i+1) 
printf(\"%d is missing\",i+1); } 
this takes o(n) time    and o(1) space
====================================== **     ,我们可以使用以下代码查找重复和缺失的值:
    int size = 8;
    int arr[] = {1,2,3,5,3};
    int result[] = new int[size];

    for(int i =0; i < arr.length; i++)
    {
        if(result[arr[i]-1] == 1)
        {
            System.out.println(\"repeating: \" + (arr[i]));
        }
        result[arr[i]-1]++;
    }

    for(int i =0; i < result.length; i++)
    {
        if(result[i] == 0)
        {
            System.out.println(\"missing: \" + (i+1));
        }
    }
    ,这是一个面试问题:数字缺失。 条件1:数组不得包含任何重复项。 完整的解决方案是:
public class Solution5 {
public static void main(String[] args) {

    int a[] = { 1,8,6,7,10};
    Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
    int ch = a[i];   
    if(start == ch) {
        start++;
    }else {
     list.add(start);
     start++;
     //must do this 
     i--;
    }
}//for
System.out.println(list);
}//main

}