web-dev-qa-db-fra.com

Trouver 2 nombres manquants dans un tableau d'entiers avec deux valeurs manquantes

Comment est-ce que tu fais ça? Les valeurs ne sont pas triées mais sont de [1..n] Exemple de tableau [3,1,2,5,7,8]. Réponse: 4, 6

J'ai vu cette solution dans un autre post , mais je ne comprends pas la dernière étape:

  • Trouve la somme des nombres S = a1 + ... + an.
  • Trouve aussi la somme des carrés T = a1² + ... + an².
  • Vous savez que la somme doit être S '= 1 + ... + n = n (n + 1)/2
  • Vous savez que la somme des carrés devrait être T '= 1² + ... + n² = n (n + 1) (2n + 1)/6.
  • Maintenant, configurez le système d'équations suivant x + y = S'-S, x² + y² = T'-T.
  • Résoudre en écrivant x² + y² = (x + y) ²-2xy => xy = ((S'-S) ²- (T'-T))/2.
  • Et maintenant, les nombres ne sont que les racines du quadratique dans z: z²- (S'-S) z + ((S'-S) ²- (T'-T))/2 = 0.

Quelle est l'explication de la mise en place de cette équation quadratique dans la dernière étape avec z comme inconnu? Quelle est l'intuition derrière cela étant la solution à ce problème?

10
ordinary

Cette méthode n'est pas recommandée car elle présente des problèmes de débordement integername__. Utilisez donc la méthode XORpour trouver les deux nombres, ce qui est très performant. Si vous êtes intéressé, je peux expliquer.

Selon la demande de @ordinary ci-dessous, j'explique l'algorithme:

EDIT

Supposons que l'élément maximum du tableau a[] soit Bc'est-à-dire supposons a[]={1,2,4} et ici 3 et 5 ne sont pas présents dans un élément [] afin que max soit B=5.

  • xortous les éléments du tableau aà Xname__
  • xortous les éléments de 1 à Bà xname__
  • trouver le jeu de bits le plus à gauche de xby x = x &(~(x-1));
  • Maintenant, si a[i] ^ x == x que xora[i] à pelse xoravec qname__
  • Passons maintenant à kde 1 à Bsi k ^ x == x que xoravec pelse xoravec qname__
  • Imprimez maintenant pet qname__

preuve:

Soit a = {1,2,4} et B= 5, c'est-à-dire que de 1 à 5, les nombres manquants sont 3 et 5

Une fois que nous avons XORéléments de aet les nombres de 1 à 5, nous sommes partis avec XORde 3 et 5 i.e. xname__.

Maintenant, lorsque nous trouvons le jeu de bits le plus à gauche de xname__, il ne s'agit que du bit le plus à gauche différent parmi 3 et 5. (3--> 011, 5 --> 101 et x = 010x = 3 ^ 5)

Après cela, nous essayons de diviser en deux groupes en fonction du jeu de bits xafin que les deux groupes soient:

p = 2 , 2 , 3 (all has the 2nd last bit set)

q = 1, 1, 4, 4, 5 (all has the 2nd last bit unset)

si nous XORles éléments de pentre eux, nous trouverons 3 et de la même manière si nous xortous les éléments de qentre eux que nous aurons 5. D'où la réponse.

code en Java

public void findNumbers(int[] a, int B){
    int x=0;
    for(int i=0; i<a.length;i++){
        x=x^a[i];
    }
    for(int i=1;i<=B;i++){
        x=x^i;
    }
    x = x &(~(x-1));
    int p=0, q=0;
    for(int i=0;i<a.length;i++){
        if((a[i] & x) == x){
            p=p^a[i];
        }
        else{
            q=q^a[i];
        }   
    }
    for(int i=1;i<=B;i++){
        if((i & x) == x){
            p=p^i;
        }
        else{
            q=q^i;
        }
    }

    System.out.println("p: "+p+" : "+q);
}
26
Trying

Soit x et y les racines d’une équation quadratique.

  • Somme des racines, SUM = x + y
  • Produit des racines, PRODUCT = x * y

Si nous connaissons la somme et le produit, nous pouvons reconstruire l'équation quadratique de la manière suivante:

z^2 - (SUM)z + (PRODUCT) = 0

Dans l'algorithme que vous avez mentionné, nous trouvons la somme et le produit, et à partir de cela, nous reconstruisons l'équation quadratique en utilisant la formule ci-dessus.

Si vous êtes intéressé par une dérivation détaillée, voici une référence . Lire "Reconstruction de l'équation quadratique à partir de la somme et du produit des racines" .

10
slider

J'ai un algorithme pour le problème ci-dessus.

Supposer

Actual Series: 1 2 3 4 5 6          a:sum=21 product= 720
Missing Number series: 1 * 3 4 * 6  b:sum=14 product= 72

a+b=21-14= 7 , ab=720/72=10

Maintenant, nous devons trouver a-b= sqrt[(a+b)^2 -4ab].

Si vous calculez:

a-b= 3

À présent

a+b=7
a-b=3

Ajoutez les deux équations:

2a=10, a=5

alors b=7-5=2 so, 2 et 5 sont manquants.

5
Manik Gupta

Commençant par

x+y == SUM
xy == PRODUCT

Il y a deux cas. Si PRODUCT vaut zéro, l'un des chiffres est 0 et l'autre SUM. Sinon, les deux sont non nuls; on peut multiplier la première équation par x sans changer l'égalité:

x*x + xy == x*SUM

Remplacez la deuxième équation:

x*x + PRODUCT = x*SUM

et réorganiser sous la forme habituelle

x*x - x*SUM + PRODUCT = 0

Pour que

x = SUM/2 + sqrt(SUM*SUM - 4*PRODUCT)/2
y = SUM/2 - sqrt(SUM*SUM - 4*PRODUCT)/2
4
Ben Voigt

Implémentation Java: (Basé sur @Ben Voigt)

BigInteger fact=1;
int sum=0;
int prod=1;
int x,y; // The 2 missing numbers
int n=a.length;
int max=MIN_VALUE;

for (int i=0; i<a.length;i++){
  sum+=a[i]; //sums the existing numbers
  prod*=a[i]; //product the existing numbers
  if (max<a[i]) //searches for the biggest number in the array
     max=a[i];
}

while(max!=1){ //factorial for the maximum number
     fact*=max;
     max--;
}
sum=(n*(n+1))/2 - sum; //the sum of the 2 missing numbers
prod=fact/prod; //the product of the 2 missing numbers

x=sum/2 + Math.sqrt(sum*sum - 4*prod)/2;
y=sum/2 - Math.sqrt(sum*sum - 4*prod)/2;
2
OhadM
Below is the generic answer in Java code for any number of missing numbers in a given array
//assumes that there are no duplicates
a = [1,2,3,4,5]
b = [1,2,5]
a-b=[3,4]

public list<integer> find(int[] input){
  int[] a= new int[] {1,2,3,4,5};//create a new array without missing numbers
  List<Integer> l = new ArrayList<Integer>();//list for missing numbers
  Map<Integer,Integer> m = new HashMap<Integer>();

  //populate a hashmap with the elements in the new array
  for(int i=0;i<input.length;i++){  
   m.put(input[i], 1);
  }
//loop through the given input array and check for missing numbers
 for(int i=0;i<a.length;i++){
  if (!m.contains(input[i]))
   l.add(input[i]);
}
 return l;
}
1
user1789685

J'espère que ce programme vous sera utile à tous. J'ai pris la limite jusqu'à 10, vous pouvez le faire de la même manière, utilisez simplement n comme limite et effectuez les mêmes opérations.

#include <iostream>
#include<math.h>

using namespace std;

int main()
{
    int i,x[100],sum1=0,sum2=0,prod1=1,prod2=1,k,j,p=0;
    cout<<"Enter 8 elements less than 10, they should be non recurring"<<endl;
    for(i=0;i<8;i++)
    {
        cin>>x[i];
    }
    sum1=((10)*(11))/2;
    for(i=0;i<8;i++)
    {
        sum2+=x[i];
    }
    k=sum1-sum2;
    for(i=1;i<10;i++)
    {
        prod1=prod1*i;
    }
    for(i=0;i<8;i++)
    {
        prod2=prod2*x[i];
    }
    j=prod1/prod2;
    p=sqrt((k*k)-(4*j));
    cout<<"One missing no:"<<p/2<<endl;
    cout<<"Second missing no:"<<k-p/2<<endl;


}
0
Shivam Sharda
#include <stdio.h>
#include <math.h>

/*
    the sum should be 1+...+n = n(n+1)/2
    the sum of squares should be 1^2+...+n^2 = n(n+1)(2n+1)/6.
*/

void find_missing_2_numbers(int *arr, int n);

int main()
{
    int arr[] = {3,7,1,6,8,5};

    find_missing_2_numbers(arr, 8);

    return 0;
}

void find_missing_2_numbers(int *arr, int n)
{

    int i, size, a, b, sum, sum_of_sqr, a_p_b, as_p_bs, a_i_b, a_m_b;
    size = n - 2;

    sum = 0;
    sum_of_sqr = 0;
    for (i = 0; i < size; i++)
    {
        sum += arr[i];
        sum_of_sqr += (arr[i] * arr[i]);
    }

    a_p_b = (n*(n+1))/2 - sum;
    as_p_bs = (n*(n+1)*(2 * n + 1))/6 - sum_of_sqr;
    a_i_b = ((a_p_b * a_p_b) - as_p_bs ) / 2;
    a_m_b = (int) sqrt((a_p_b * a_p_b) - 4 * a_i_b);
    a = (a_p_b + a_m_b) / 2;
    b = a_p_b - a;

    printf ("A: %d, B: %d\n", a, b);
}
0
Alok Singh