web-dev-qa-db-fra.com

Étant donné un tableau de nombres, retourne un tableau de produits de tous les autres nombres (pas de division)

On m'a posé cette question lors d'un entretien d'embauche, et j'aimerais savoir comment les autres pourraient le résoudre. Je suis plus à l'aise avec Java, mais les solutions dans d'autres langues sont les bienvenues.

Avec un tableau de nombres, nums, retourne un tableau de nombres products, où products[i] est le produit de tous les nums[j], j != i.

Input : [1, 2, 3, 4, 5]
Output: [(2*3*4*5), (1*3*4*5), (1*2*4*5), (1*2*3*5), (1*2*3*4)]
      = [120, 60, 40, 30, 24]

Vous devez le faire dans O(N) sans utiliser de division.

168
polygenelubricants

Une explication de la méthode polygenelubricants est la suivante: L'astuce consiste à construire les tableaux (dans le cas de 4 éléments)

{              1,         a[0],    a[0]*a[1],    a[0]*a[1]*a[2],  }
{ a[1]*a[2]*a[3],    a[2]*a[3],         a[3],                 1,  }

Les deux peuvent être réalisés dans O(n) en commençant par les bords gauche et droit respectivement.

Puis multiplier les deux tableaux élément par élément donne le résultat souhaité

Mon code ressemblerait à quelque chose comme ça:

int a[N] // This is the input
int products_below[N];
p=1;
for(int i=0;i<N;++i) {
  products_below[i]=p;
  p*=a[i];
}

int products_above[N];
p=1;
for(int i=N-1;i>=0;--i) {
  products_above[i]=p;
  p*=a[i];
}

int products[N]; // This is the result
for(int i=0;i<N;++i) {
  products[i]=products_below[i]*products_above[i];
}

Si vous devez être O(1) aussi, vous pouvez le faire (ce qui est moins clair à mon humble avis)

int a[N] // This is the input
int products[N];

// Get the products below the current index
p=1;
for(int i=0;i<N;++i) {
  products[i]=p;
  p*=a[i];
}

// Get the products above the curent index
p=1;
for(int i=N-1;i>=0;--i) {
  products[i]*=p;
  p*=a[i];
}
227
Michael Anderson

Voici une petite fonction récursive (en C++) pour effectuer la modification en place. Cependant, il nécessite O(n) un espace supplémentaire (sur la pile). En supposant que le tableau est dans a et que N détient la longueur du tableau, nous avons

int multiply(int *a, int fwdProduct, int indx) {
    int revProduct = 1;
    if (indx < N) {
       revProduct = multiply(a, fwdProduct*a[indx], indx+1);
       int cur = a[indx];
       a[indx] = fwdProduct * revProduct;
       revProduct *= cur;
    }
    return revProduct;
}
48
Jasmeet

Voici ma tentative de le résoudre en Java. Toutes mes excuses pour le formatage non standard, mais le code comporte beaucoup de duplications et c'est le mieux que je puisse faire pour le rendre lisible.

import Java.util.Arrays;

public class Products {
    static int[] products(int... nums) {
        final int N = nums.length;
        int[] prods = new int[N];
        Arrays.fill(prods, 1);
        for (int
           i = 0, pi = 1    ,  j = N-1, pj = 1  ;
           (i < N)         && (j >= 0)          ;
           pi *= nums[i++]  ,  pj *= nums[j--]  )
        {
           prods[i] *= pi   ;  prods[j] *= pj   ;
        }
        return prods;
    }
    public static void main(String[] args) {
        System.out.println(
            Arrays.toString(products(1, 2, 3, 4, 5))
        ); // prints "[120, 60, 40, 30, 24]"
    }
}

Les invariants de boucle sont pi = nums[0] * nums[1] *.. nums[i-1] et pj = nums[N-1] * nums[N-2] *.. nums[j+1]. La partie i à gauche est la logique "préfixe" et la partie j à droite est la logique "suffixe".


One-Liner récursif

Jasmeet a donné une (belle!) Solution récursive; Je l'ai transformé en ce one-liner Java (hideux!). Il fait modification sur place, avec O(N) espace temporaire dans la pile.

static int multiply(int[] nums, int p, int n) {
    return (n == nums.length) ? 1
      : nums[n] * (p = multiply(nums, nums[n] * (nums[n] = p), n + 1))
          + 0*(nums[n] *= p);
}

int[] arr = {1,2,3,4,5};
multiply(arr, 1, 0);
System.out.println(Arrays.toString(arr));
// prints "[120, 60, 40, 30, 24]"
15
polygenelubricants

Traduire la solution de Michael Anderson en Haskell:

otherProducts xs = zipWith (*) below above

     where below = scanl (*) 1 $ init xs

           above = tail $ scanr (*) 1 xs
14
fredoverflow

Contournant sournoisement la règle du "pas de division":

sum = 0.0
for i in range(a):
  sum += log(a[i])

for i in range(a):
  output[i] = exp(sum - log(a[i]))
12
sth

Voilà une solution simple et propre à la complexité O(N):

int[] a = {1,2,3,4,5};
    int[] r = new int[a.length];
    int x = 1;
    r[0] = 1;
    for (int i=1;i<a.length;i++){
        r[i]=r[i-1]*a[i-1];
    }
    for (int i=a.length-1;i>0;i--){
        x=x*a[i];
        r[i-1]=x*r[i-1];
    }
    for (int i=0;i<r.length;i++){
        System.out.println(r[i]);
    }
10
raoadnan

C++, O (n):

long long prod = accumulate(in.begin(), in.end(), 1LL, multiplies<int>());
transform(in.begin(), in.end(), back_inserter(res),
          bind1st(divides<long long>(), prod));
5
wilhelmtell
  1. Voyage à gauche-> droite et continue à économiser du produit. Appelez ça du passé. -> O (n)
  2. Voyage Droite -> gauche garder le produit. Appelez ça du futur. -> O (n)
  3. Résultat [i] = Passé [i-1] * futur [i + 1] -> O (n)
  4. Passé [-1] = 1; et Future [n + 1] = 1;

O(n)

5
user3177227

Voici ma solution en C++ moderne. Il utilise std::transform et est assez facile à mémoriser.

Code en ligne (wandbox).

#include<algorithm>
#include<iostream>
#include<vector>

using namespace std;

vector<int>& multiply_up(vector<int>& v){
    v.insert(v.begin(),1);
    transform(v.begin()+1, v.end()
             ,v.begin()
             ,v.begin()+1
             ,[](auto const& a, auto const& b) { return b*a; }
             );
    v.pop_back();
    return v;
}

int main() {
    vector<int> v = {1,2,3,4,5};
    auto vr = v;

    reverse(vr.begin(),vr.end());
    multiply_up(v);
    multiply_up(vr);
    reverse(vr.begin(),vr.end());

    transform(v.begin(),v.end()
             ,vr.begin()
             ,v.begin()
             ,[](auto const& a, auto const& b) { return b*a; }
             );

    for(auto& i: v) cout << i << " "; 
}
3

C'est O (n ^ 2) mais f # est tellement beau:

List.fold (fun seed i -> List.mapi (fun j x -> if i=j+1 then x else x*i) seed) 
          [1;1;1;1;1]
          [1..5]
2
Lars
def productify(arr, prod, i):
    if i < len(arr):
            prod.append(arr[i - 1] * prod[i - 1]) if i > 0 else prod.append(1)
            retval = productify(arr, prod, i + 1)
            prod[i] *= retval
            return retval * arr[i]
    return 1

arr = [1, 2, 3, 4, 5] prod = [] productify (arr, prod, 0) produit d'impression

1
Nitin

Il existe également une solution O (N ^ (3/2)) non optimale . C'est assez intéressant, cependant.

Tout d'abord, pré-traiter chaque multiplication partielle de taille N ^ 0.5 (ceci est effectué avec une complexité temporelle de O(N)). Ensuite, le calcul du nombre multiple d’autres valeurs de chaque nombre peut être effectué en 2 * O (N ^ 0.5) fois (pourquoi?) et multipliez le résultat avec ((N ^ 0.5) - 1) nombres appartenant au groupe du nombre actuel). En faisant cela pour chaque numéro, on peut obtenir le temps O (N ^ (3/2)).

Exemple:

4 6 7 2 3 1 9 5 8

résultats partiels: 4 * 6 * 7 = 168 2 * 3 * 1 = 6 9 * 5 * 8 = 360

Pour calculer la valeur de 3, il faut multiplier les valeurs des autres groupes par 168 * 360, puis par 2 * 1.

1
kolistivra

Basé sur la réponse de Billz - désolé je ne peux pas commenter, mais voici une version de scala qui gère correctement les éléments en double dans la liste, et qui est probablement O (n):

val list1 = List(1, 7, 3, 3, 4, 4)
val view = list1.view.zipWithIndex map { x => list1.view.patch(x._2, Nil, 1).reduceLeft(_*_)}
view.force

résultats: 

List(1008, 144, 336, 336, 252, 252)
1
junkgui

Pour être complet, voici le code en Scala:

val list1 = List(1, 2, 3, 4, 5)
for (elem <- list1) println(list1.filter(_ != elem) reduceLeft(_*_))

Ceci imprimera ce qui suit:

120
60
40
30
24

Le programme filtrera l'elem actuel (_! = Elem); et multipliez la nouvelle liste avec la méthode reductionLeft. Je pense que ce sera O(n) si vous utilisez la vue scala ou Iterator pour eval paresseux. 

1
Billz

Je suis habitué à C #:

    public int[] ProductExceptSelf(int[] nums)
    {
        int[] returnArray = new int[nums.Length];
        List<int> auxList = new List<int>();
        int multTotal = 0;

        // If no zeros are contained in the array you only have to calculate it once
        if(!nums.Contains(0))
        {
            multTotal = nums.ToList().Aggregate((a, b) => a * b);

            for (int i = 0; i < nums.Length; i++)
            {
                returnArray[i] = multTotal / nums[i];
            }
        }
        else
        {
            for (int i = 0; i < nums.Length; i++)
            {
                auxList = nums.ToList();
                auxList.RemoveAt(i);
                if (!auxList.Contains(0))
                {
                    returnArray[i] = auxList.Aggregate((a, b) => a * b);
                }
                else
                {
                    returnArray[i] = 0;
                }
            }
        }            

        return returnArray;
    }
1
RodrigoCampos

Précalculez le produit des nombres à gauche et à droite de chaque élément . Pour chaque élément, la valeur souhaitée est le produit des produits de ses voisins. 

#include <stdio.h>

unsigned array[5] = { 1,2,3,4,5};

int main(void)
{
unsigned idx;

unsigned left[5]
        , right[5];
left[0] = 1;
right[4] = 1;

        /* calculate products of numbers to the left of [idx] */
for (idx=1; idx < 5; idx++) {
        left[idx] = left[idx-1] * array[idx-1];
        }

        /* calculate products of numbers to the right of [idx] */
for (idx=4; idx-- > 0; ) {
        right[idx] = right[idx+1] * array[idx+1];
        }

for (idx=0; idx <5 ; idx++) {
        printf("[%u] Product(%u*%u) = %u\n"
                , idx, left[idx] , right[idx]  , left[idx] * right[idx]  );
        }

return 0;
}

Résultat:

$ ./a.out
[0] Product(1*120) = 120
[1] Product(1*60) = 60
[2] Product(2*20) = 40
[3] Product(6*5) = 30
[4] Product(24*1) = 24

(MISE À JOUR: maintenant je regarde de plus près, cela utilise la même méthode que Michael Anderson, Daniel Migowski et polygenelubricants ci-dessus) 

1
wildplasser

Rusé: 

Utilisez le suivant:

public int[] calc(int[] params) {

int[] left = new int[n-1]
in[] right = new int[n-1]

int fac1 = 1;
int fac2 = 1;
for( int i=0; i<n; i++ ) {
    fac1 = fac1 * params[i];
    fac2 = fac2 * params[n-i];
    left[i] = fac1;
    right[i] = fac2; 
}
fac = 1;

int[] results = new int[n];
for( int i=0; i<n; i++ ) {
    results[i] = left[i] * right[i];
}

Oui, je suis sûr que j'ai raté du i-1 au lieu de i, mais c’est le moyen de le résoudre.

1
Daniel Migowski
public static void main(String[] args) {
    int[] arr = { 1, 2, 3, 4, 5 };
    int[] result = { 1, 1, 1, 1, 1 };
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < i; j++) {
            result[i] *= arr[j];

        }
        for (int k = arr.length - 1; k > i; k--) {
            result[i] *= arr[k];
        }
    }
    for (int i : result) {
        System.out.println(i);
    }
}

Cette solution que je suis venu avec et je l'ai trouvé si clair que pensez-vous!

1
Kareem

Ajout de ma solution javascript ici car je n'ai trouvé personne qui le suggère . Quel est le partage, sauf pour compter le nombre de fois que vous pouvez extraire un nombre d'un autre nombre? Je suis allé à travers le calcul du produit de l'ensemble du tableau, puis itérer sur chaque élément, et soustrayant l'élément actuel jusqu'à zéro:

//No division operation allowed
// keep substracting divisor from dividend, until dividend is zero or less than divisor
function calculateProducsExceptCurrent_NoDivision(input){
  var res = [];
  var totalProduct = 1;
  //calculate the total product
  for(var i = 0; i < input.length; i++){
    totalProduct = totalProduct * input[i];
  }
  //populate the result array by "dividing" each value
  for(var i = 0; i < input.length; i++){
    var timesSubstracted = 0;
    var divisor = input[i];
    var dividend = totalProduct;
    while(divisor <= dividend){
      dividend = dividend - divisor;
      timesSubstracted++;
    }
    res.Push(timesSubstracted);
  }
  return res;
}
1
soulus

Voici une implémentation en C
O (n) complexité temporelle .
CONTRIBUTION

#include<stdio.h>
int main()
{
    int x;
    printf("Enter The Size of Array : ");
    scanf("%d",&x);
    int array[x-1],i ;
    printf("Enter The Value of Array : \n");
      for( i = 0 ; i <= x-1 ; i++)
      {
          printf("Array[%d] = ",i);
          scanf("%d",&array[i]);
      }
    int left[x-1] , right[x-1];
    left[0] = 1 ;
    right[x-1] = 1 ;
      for( i = 1 ; i <= x-1 ; i++)
      {
          left[i] = left[i-1] * array[i-1];
      }
    printf("\nThis is Multiplication of array[i-1] and left[i-1]\n");
      for( i = 0 ; i <= x-1 ; i++)
      {
        printf("Array[%d] = %d , Left[%d] = %d\n",i,array[i],i,left[i]);
      }
      for( i = x-2 ; i >= 0 ; i--)
      {
          right[i] = right[i+1] * array[i+1];
      }
   printf("\nThis is Multiplication of array[i-1] and right[i-1]\n");
      for( i = 0 ; i <= x-1 ; i++)
      {
        printf("Array[%d] = %d , Right[%d] = %d\n",i,array[i],i,right[i]);
      }
    printf("\nThis is Multiplication of Right[i] * Left[i]\n");
      for( i = 0 ; i <= x-1 ; i++)
      {
          printf("Right[%d] * left[%d] = %d * %d = %d\n",i,i,right[i],left[i],right[i]*left[i]);
      }
    return 0 ;
}


SORTIE

    Enter The Size of Array : 5
    Enter The Value of Array :
    Array[0] = 1
    Array[1] = 2
    Array[2] = 3
    Array[3] = 4
    Array[4] = 5

    This is Multiplication of array[i-1] and left[i-1]
    Array[0] = 1 , Left[0] = 1
    Array[1] = 2 , Left[1] = 1
    Array[2] = 3 , Left[2] = 2
    Array[3] = 4 , Left[3] = 6
    Array[4] = 5 , Left[4] = 24

    This is Multiplication of array[i-1] and right[i-1]
    Array[0] = 1 , Right[0] = 120
    Array[1] = 2 , Right[1] = 60
    Array[2] = 3 , Right[2] = 20
    Array[3] = 4 , Right[3] = 5
    Array[4] = 5 , Right[4] = 1

    This is Multiplication of Right[i] * Left[i]
    Right[0] * left[0] = 120 * 1 = 120
    Right[1] * left[1] = 60 * 1 = 60
    Right[2] * left[2] = 20 * 2 = 40
    Right[3] * left[3] = 5 * 6 = 30
    Right[4] * left[4] = 1 * 24 = 24

    Process returned 0 (0x0)   execution time : 6.548 s
    Press any key to continue.
0
Rishabh Jain

On m'a posé cette question récemment et, alors que je ne pouvais pas obtenir O(N) au cours de celle-ci, j'avais une approche différente (malheureusement, O (N ^ 2)), mais je pensais que je partagerais quand même.

Convertissez d'abord en List<Integer>.

Boucle dans la matrice d'origine array.length() fois.

Utilisez une boucle while pour multiplier le prochain ensemble de nombres requis:

while (temp < list.size() - 1) {
    res *= list.get(temp);
    temp++;
}

Ajoutez ensuite res à un nouveau tableau (ce que vous avez bien sûr déclaré précédemment), puis ajoutez la valeur at array[i] à la List, et continuez ainsi.

Je sais que ce ne sera pas très utile, mais c’est ce que j’ai trouvé sous la pression d’une interview :)

    int[] array = new int[]{1, 2, 3, 4, 5};
    List<Integer> list = Arrays.stream(array).boxed().collect(Collectors.toList());
    int[] newarray = new int[array.length];
    int res = 1;
    for (int i = 0; i < array.length; i++) {
        int temp = i;
        while (temp < list.size() - 1) {
            res *= list.get(temp);
            temp++;
        }
        newarray[i] = res;
        list.add(array[i]);
        res = 1;
    }

Sortie: [24, 120, 60, 40, 30]

0
achAmháin

Voici une version simple de Scala en temps linéaire O(n):

 def getProductEff (in: Seq [Int]): Seq [Int] = {

 // crée une liste qui a produit de chaque élément à gauche de cet élément 
 val fromLeft = in.foldLeft ((1, Seq.empty [Int])) ((ac, i) => (i * ac._1, ac._2: + ac._1)) ._ 2 

 // crée une liste qui produit chaque élément à droite de cet élément, identique à l'étape précédente mais en sens inverse 
 val fromRight = in.reverse.foldLeft ((1, Seq.empty [Int])) ((ac, i) => (i * ac._1, ac._2: + ac._1)) ._ 2. inverse

 // fusionne les deux listes par produit dans index 
 in.indices.map (i => fromLeft (i) * fromRight (i)) 

} 

Cela fonctionne parce que la réponse est essentiellement un tableau qui produit tous les éléments à gauche et à droite. 

0
prithwin
 {-
 Solution récursive utilisant des sous-ensembles de sqrt (n). S'exécute dans O (n) .

 Calcule de manière récursive la solution sur sqrt (n) sous-ensembles de taille sqrt (n). 
 Ensuite, on recourt à la somme du produit de chaque sous-ensemble .
 Puis, pour chaque élément de chaque sous-ensemble, le produit est calculé avec 
 La somme du produit de tous les autres produits .
 Ensuite, aplatit tous les sous-ensembles ..__ La récurrence au moment de l'exécution est T(n) = sqrt (n) * T (sqrt (n)) + T(sqrt(n)) + n 

 Supposons que T(n) ≤ cn dans O (n) .

 T (n) = sqrt (n) * T (sqrt (n)) + T(sqrt(n)) + n 
 ≤ sqrt (n) * c * sqrt (n) + c * sqrt (n) + n 
 ≤ c * n + c * sqrt (n) + n 
 ≤ (2c + 1) * n 
 O (n) 

 Notez que plafond (sqrt (n)) peut être calculé à l'aide d'une recherche binaire 
 Et O(logn) itérations, si l'instruction sqrt n'est pas autorisée
-} 

 otherProducts [] = [] 
 otherProducts [x] = [1] 
 otherProducts [x, y] = [y, x] 
 otherProducts a = foldl ' (++) [] $ zipWith (\ sp -> map (* p) s) solvedSubsets subsetOtherProducts 
 où 
 n = longueur a 

 - Taille du sous-ensemble. Exigez que 1 <s <n .
 s = plafond $ sqrt $ fromIntegral n 

 solvedSubsets = mapper les autres sous-ensembles deProduits 
 subsetOtherProducts = otherProducts $ Sous-ensembles de produits cartographiques 

 sous-ensembles = inverse $ boucle a [] 
 où la boucle [] acc = acc 
 loop a acc = boucle (drop s a) ((prenez s a): acc) 
0
Fysx
int[] b = new int[] { 1, 2, 3, 4, 5 };            
int j;
for(int i=0;i<b.Length;i++)
{
  int prod = 1;
  int s = b[i];
  for(j=i;j<b.Length-1;j++)
  {
    prod = prod * b[j + 1];
  }
int pos = i;    
while(pos!=-1)
{
  pos--;
  if(pos!=-1)
     prod = prod * b[pos];                    
}
Console.WriteLine("\n Output is {0}",prod);
}
0
Pushkar

Voici la version python

  # This solution use O(n) time and O(n) space
  def productExceptSelf(self, nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    N = len(nums)
    if N == 0: return

    # Initialzie list of 1, size N
    l_prods, r_prods = [1]*N, [1]*N

    for i in range(1, N):
      l_prods[i] = l_prods[i-1] * nums[i-1]

    for i in reversed(range(N-1)):
      r_prods[i] = r_prods[i+1] * nums[i+1]

    result = [x*y for x,y in Zip(l_prods,r_prods)]
    return result

  # This solution use O(n) time and O(1) space
  def productExceptSelfSpaceOptimized(self, nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    N = len(nums)
    if N == 0: return

    # Initialzie list of 1, size N
    result = [1]*N

    for i in range(1, N):
      result[i] = result[i-1] * nums[i-1]

    r_prod = 1
    for i in reversed(range(N)):
      result[i] *= r_prod
      r_prod *= nums[i]

    return result
0
R.F

Eh bien, cette solution peut être considérée comme celle de C/C++ . Disons que nous avons un tableau "a" contenant n éléments comme a [n], le pseudo-code serait comme ci-dessous.

for(j=0;j<n;j++)
  { 
    prod[j]=1;

    for (i=0;i<n;i++)
    {   
        if(i==j)
        continue;  
        else
        prod[j]=prod[j]*a[i];
  }
0
Vijay

Voici un exemple légèrement fonctionnel, utilisant C #:

            Func<long>[] backwards = new Func<long>[input.Length];
            Func<long>[] forwards = new Func<long>[input.Length];

            for (int i = 0; i < input.Length; ++i)
            {
                var localIndex = i;
                backwards[i] = () => (localIndex > 0 ? backwards[localIndex - 1]() : 1) * input[localIndex];
                forwards[i] = () => (localIndex < input.Length - 1 ? forwards[localIndex + 1]() : 1) * input[localIndex];
            }

            var output = new long[input.Length];
            for (int i = 0; i < input.Length; ++i)
            {
                if (0 == i)
                {
                    output[i] = forwards[i + 1]();
                }
                else if (input.Length - 1 == i)
                {
                    output[i] = backwards[i - 1]();
                }
                else
                {
                    output[i] = forwards[i + 1]() * backwards[i - 1]();
                }
            }

Je ne suis pas entièrement certain que c'est O (n), en raison de la semi-récursion des Func créés, mais mes tests semblent indiquer que c'est O(n) dans le temps.

0
Ian Newson

Mon premier essai, en Python. O (2n):

def product(l):
    product = 1
    num_zeroes = 0
    pos_zero = -1

    # Multiply all and set positions
    for i, x in enumerate(l):
        if x != 0:
            product *= x
            l[i] = 1.0/x
        else:
            num_zeroes += 1
            pos_zero = i

    # Warning! Zeroes ahead!
    if num_zeroes > 0:
        l = [0] * len(l)

        if num_zeroes == 1:
            l[pos_zero] = product

    else:
        # Now set the definitive elements
        for i in range(len(l)):
            l[i] = int(l[i] * product)

    return l


if __== "__main__":
    print("[0, 0, 4] = " + str(product([0, 0, 4])))
    print("[3, 0, 4] = " + str(product([3, 0, 4])))
    print("[1, 2, 3] = " + str(product([1, 2, 3])))
    print("[2, 3, 4, 5, 6] = " + str(product([2, 3, 4, 5, 6])))
    print("[2, 1, 2, 2, 3] = " + str(product([2, 1, 2, 2, 3])))

Sortie:

[0, 0, 4] = [0, 0, 0]
[3, 0, 4] = [0, 12, 0]
[1, 2, 3] = [6, 3, 2]
[2, 3, 4, 5, 6] = [360, 240, 180, 144, 120]
[2, 1, 2, 2, 3] = [12, 24, 12, 12, 8]
0
Baltasarq

Voici un autre concept simple qui résout le problème dans O(N).

        int[] arr = new int[] {1, 2, 3, 4, 5};
        int[] outArray = new int[arr.length]; 
        for(int i=0;i<arr.length;i++){
            int res=Arrays.stream(arr).reduce(1, (a, b) -> a * b);
            outArray[i] = res/arr[i];
        }
        System.out.println(Arrays.toString(outArray));
0
SiddP

Voici ma solution concise en utilisant python.

from functools import reduce

def excludeProductList(nums_):
    after = [reduce(lambda x, y: x*y, nums_[i:]) for i in range(1, len(nums_))] + [1]
    before = [1] + [reduce(lambda x, y: x*y, nums_[:i]) for i in range(1, len(nums_))]
    zippedList =  list(Zip(before, after))
    finalList = list(map(lambda x: x[0]*x[1], zippedList))
    return finalList

Solution de rubis

a = [1,2,3,4]
result = []
a.each {|x| result.Push( (a-[x]).reject(&:zero?).reduce(:*)) }
puts result

Une autre solution, Utilisation de la division. avec deux fois la traversée . Multipliez tous les éléments puis commencez à le diviser par chaque élément.

0
Alam

J'ai une solution avec O(n) espace et O(n^2) complexité temporelle fournie ci-dessous, 

public static int[] findEachElementAsProduct1(final int[] arr) {

        int len = arr.length;

//        int[] product = new int[len];
//        Arrays.fill(product, 1);

        int[] product = IntStream.generate(() -> 1).limit(len).toArray();


        for (int i = 0; i < len; i++) {

            for (int j = 0; j < len; j++) {

                if (i == j) {
                    continue;
                }

                product[i] *= arr[j];
            }
        }

        return product;
    }
0
Arefe

Nous pouvons exclure le nums[j] (où j != i) de la liste en premier, puis obtenir le produit du reste; Ce qui suit est un python way pour résoudre ce casse-tête:

def products(nums):
    return [ reduce(lambda x,y: x * y, nums[:i] + nums[i+1:]) for i in range(len(nums)) ]
print products([1, 2, 3, 4, 5])

[out]
[120, 60, 40, 30, 24]
0
Quinn
function solution($array)
{
    $result = [];
    foreach($array as $key => $value){
        $copyOfOriginalArray = $array;
        unset($copyOfOriginalArray[$key]);
        $result[$key] = multiplyAllElemets($copyOfOriginalArray);
    }
    return $result;
}

/**
 * multiplies all elements of array
 * @param $array
 * @return int
 */
function multiplyAllElemets($array){
    $result = 1;
    foreach($array as $element){
        $result *= $element;
    }
    return $result;
}

$array = [1, 9, 2, 7];

print_r(solution($array));
0
Farid Movsumov

Voici mon code:

int multiply(int a[],int n,int nextproduct,int i)
{
    int prevproduct=1;
    if(i>=n)
        return prevproduct;
    prevproduct=multiply(a,n,nextproduct*a[i],i+1);
    printf(" i=%d > %d\n",i,prevproduct*nextproduct);
    return prevproduct*a[i];
}

int main()
{
    int a[]={2,4,1,3,5};
    multiply(a,5,1,0);
    return 0;
}
0
Anantha Krishnan

// C'est la solution récursive en Java // Appelé comme suit à partir du produit principal (a, 1,0);

public static double product(double[] a, double fwdprod, int index){
    double revprod = 1;
    if (index < a.length){
        revprod = product2(a, fwdprod*a[index], index+1);
        double cur = a[index];
        a[index] = fwdprod * revprod;
        revprod *= cur;
    }
    return revprod;
}
0
user3552947

Une solution soignée avec O(n) runtime:

  1. Pour chaque élément, calculez le produit de tous les éléments qui se produisent avant et stockez-le dans un tableau "pre".
  2. Pour chaque élément, calculez le produit de tous les éléments apparaissant après cet élément et stockez-le dans un tableau "post"
  3. Créer un tableau final "résultat", pour un élément i,

    result[i] = pre[i-1]*post[i+1];
    
0
dhineshns