从给定的算术级数中查找缺失的数字

时间:2013-12-10 12:55:38

标签: algorithm

我遇到了这个问题,你给了一个数字N作为输入,然后是N个数字(其中3< = N< = 2500)。这些N数字是算术级数(大小为N+1)的一部分,从中删除了一个数字。所以任务是找到丢失号码。例如

5
1 3 5 9 11  

输出为7

我提出了两种方法,第二种方法通过所有测试用例,但第一种方法在某些(隐藏)情况下失败。

首先我将解释第二种方法

方法II

Let diff=(last_number-first_number)/N
 //Considering 0 based indexing
 for i=0 to (N-2)
    if( array[i+1] is not equal to (array[i]+diff))
          print (array[i]+diff)
          break

此方法通过了所有测试用例。现在我实现的第一个方法和某些测试用例失败的方法如下

方法I

 //Considering 0 based indexing
 for i=1 to (N-2)
      if (2*array[i] is not equal to (array[i-1]+array[i+1])) then
              if( (array[i]-array[i-1])< (array[i+1]-array[i]))
                      print 2*array[i]-array[i-1]
              else 
                      print 2*array[i]-array[i+1]
              break

任何人都可以解释METHOD I的问题吗?我错过了哪些案例。 感谢。

5 个答案:

答案 0 :(得分:7)

当数字按递减顺序时,方法1不起作用。

对于7 5 1输出应为3但算法将给出9。

方法2在这种情况下起作用,因为差异被正确地计算为负值并且算法相应地进行。

答案 1 :(得分:3)

虽然没有回答你原来的问题,但如果你需要一个更好的解决方案,其中O(logN)复杂度可以找到缺失的数字(如果只有一个)。使用二进制搜索。

进行二元搜索的比较

  if(a[mid] != mid*(difference)+a[0]) {

        missing_num = mid*(difference) + a[0];
        search lower half
  }

  else search higher half

答案 2 :(得分:2)

这是我在Ruby中的解决方案:

number_of_terms = gets.chomp.to_i

从STDIN获取条款数量

progression = gets.chomp.split(' ').map(&:to_i)

获取字符串,删除任何前导和尾随空格,将其拆分到数字之间的空格,然后将每个项目转换为整数。

expected_sum = (number_of_terms+1)/2.0*(progression.first+progression.last)

使用公式求和算术级数:n / 2(a [0] + a [n])。

这里除以2.0很重要。需要保持精确。

actual_sum = progression.inject(:+)

检查给定数字的总和是多少。

missing_element = (expected_sum - actual_sum).to_i

差异当然是缺失的元素。同时转换为整数以删除尾随.0

即。 4.0 =&gt; 4

puts "Missing element is: #{missing_element}"

答案 3 :(得分:1)

适用于

1)N的任何值(在示例中给出5)

2)术语之间的任何差异(在示例中给出2)

3)差异可以是+以及 - (例如:11 5 2 -1 -4)

int diff[]= new int[length-1];
for(int i = 0; i<length-1;i++){
    diff[i] = n1[i+1]-n1[i];
    System.out.println(diff[i]);
    if(i!=0){
        if(diff[i]<diff[i-1]){
            if(diff[i]<0)
                System.out.println(n1[i]+diff[i-1]);
            else
                System.out.println(n1[i-1]+diff[i]);
            break;
        }
        if(diff[i]>diff[i-1]){
            if(diff[i]<0)
                System.out.println(n1[i-1]+diff[i]);
            else
                System.out.println(n1[i]+diff[i-1]);
            break;
        }
    }
}

n1是从String存储数字数组的地方。

长度是您提供的数字。

这是优化的,如果你错过前两个数字之间的数字,那么无论你给出了多少数字,它只会循环3次

答案 4 :(得分:1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int findDelta(long *x, int n);

int main(){
    int n;
        fscanf(stdin,"%d",&n); 
        long *x= (long*) calloc(n,sizeof(long));
    long k;
    for(int i=0;i<n;i++){
        scanf("%ld",&k);
        x[i]=k;
    }

    int delta=findDelta(x,n);
    for(int i=0;i<n-1;i++){
        if (x[i+1]-x[i] != delta)
            printf("%ld\n",x[i]+delta);
    }
    free(x);    
    return 0;
}

int findDelta(long *x, int n){
    long delta1,delta2;
    delta1=x[1]-x[0];
    int d1Count=0;
    int d2Count=0;

    for(int i=1;i<n-1;i++){
        delta2=x[i+1]-x[i];
        if(delta2==delta1)
          d1Count++;
        else
          d2Count++;
    }
    if (d1Count > d2Count)
        return (delta1);
    else
        return (delta2);
}