संख्याओं की एक सरणी को देखते हुए, अन्य सभी संख्याओं के उत्पादों की वापसी सरणी (कोई विभाजन नहीं)


186

मुझे एक नौकरी के साक्षात्कार में यह सवाल पूछा गया था, और मैं जानना चाहता हूं कि दूसरे इसे कैसे हल करेंगे। मैं जावा के साथ सबसे सहज हूं, लेकिन अन्य भाषाओं में समाधान स्वागत योग्य है।

संख्याओं की एक सरणी को देखते हुए, संख्याओं की numsएक सरणी लौटाएं products, जहां products[i]सभी का उत्पाद है 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]

आपको O(N)विभाजन का उपयोग किए बिना ऐसा करना होगा ।


49
यह सवाल पिछले एक हफ्ते में कुछ बार सामने आया है; क्या आप सभी एक ही कंपनी के साथ साक्षात्कार कर रहे हैं? :)
माइकल Mrozek

मैं वर्तमान में [interview-questions]इसे खोज रहा टैग ब्राउज़ कर रहा हूं । क्या आपके पास एक लिंक है यदि आपने इसे पाया है?
पॉलीजेन लुब्रीकेंट

2
@ मिचेल: यह प्रश्न विभाजन की अनुमति देता है। मेरा स्पष्ट रूप से यह मना करता है। मैं कहता हूँ कि वे दो अलग-अलग प्रश्न हैं।
पॉलीजेन लुब्रिकेंट्स

8
लॉग (ए / बी) = लॉग (ए) -लॉग (बी) और वॉयला के साथ स्थान विभाजन!
ldog

1
कल्पना कीजिए कि अगर सरणी में 1 या 1 से अधिक शून्य हैं, तो आप मामले को कैसे संभालेंगे ??
gst

जवाबों:


257

पॉलीजेनिल लुब्रिकेंट्स विधि का स्पष्टीकरण है: चाल को एरे (4 तत्वों के मामले में) का निर्माण करना है

{              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,  }

क्रमशः बाएं और दाएं किनारों पर शुरू करके दोनों को ओ (एन) में किया जा सकता है।

फिर दो सरणियों को तत्व से गुणा करना आवश्यक परिणाम देता है

मेरा कोड कुछ इस तरह दिखेगा:

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];
}

यदि आपको अंतरिक्ष में O (1) होने की आवश्यकता है, तो आप ऐसा कर सकते हैं (जो कम स्पष्ट IMHO है)

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];
}

4
यह O (n) रनटाइम है लेकिन यह अंतरिक्ष जटिलता में O (n) भी है। आप इसे O (1) स्पेस में कर सकते हैं। मेरा मतलब है, निश्चित रूप से इनपुट और आउटपुट कंटेनरों के आकार के अलावा।
विल्हेमटेल

8
बहुत चालाक! क्या इस एल्गोरिथम का कोई नाम है?
फास्टकोडेजा

2
@MichaelAnderson ग्रेट वर्क मैन, लेकिन कृपया मुझे इसके पीछे का मुख्य तर्क बताएं और आवश्यकता पड़ने पर आपने इसे कैसे शुरू किया।
ACBalaji

3
यदि कोई तत्व 0. है तो एल्गोरिथम विफल हो जाएगा। इसलिए 0 को चेक करना न भूलें।
मणि

2
@Mani एल्गोरिथ्म ठीक है अगर वहाँ तत्व 0 पर सेट हैं। हालांकि, ऐसे तत्वों के लिए इनपुट को स्कैन करना संभव है और यदि वे पाए जाते हैं तो अधिक कुशल हो सकते हैं। यदि दो शून्य तत्व हैं, तो संपूर्ण परिणाम शून्य है, और यदि केवल एक ही है, v_i=0तो कहें कि परिणाम में केवल गैर शून्य प्रविष्टि ही ईथ तत्व है। हालाँकि मुझे संदेह है कि शून्य तत्वों का पता लगाने और गिनने के लिए पास जोड़ने से समाधान की स्पष्टता में गिरावट आएगी, और संभवत: अधिकांश मामलों में कोई वास्तविक प्रदर्शन हासिल नहीं होगा ..
माइकल एंडरसन

52

यहाँ एक छोटा सा पुनरावर्ती कार्य (C ++ में) किया जा रहा है। हालाँकि इसके लिए O (n) अतिरिक्त स्थान (स्टैक पर) की आवश्यकता होती है। मान लें कि सरणी में लंबाई है और N में सरणी लंबाई है, हमारे पास है

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;
}

क्या कोई इस पुनरावृत्ति की व्याख्या कर सकता है?
निखिल

1
@ मिनाहिल यह पहली बार पुनरावृत्ति करता है, मध्यवर्ती उत्पादों को याद करता है, अंततः के लिए संख्या उत्पाद बनाता है num[N-1]; फिर वापस रास्ते पर यह गुणन के दूसरे भाग की गणना करता है जो तब जगह में संख्या सरणी को संशोधित करने के लिए उपयोग किया जाता है।
जेक

कल्पना कीजिए कि अगर सरणी में 1 या 1 से अधिक शून्य हैं, तो आप मामले को कैसे संभालेंगे ??
gst

18

यहाँ जावा में इसे हल करने का मेरा प्रयास है। गैर-मानक स्वरूपण के लिए क्षमा याचना, लेकिन कोड में बहुत अधिक दोहराव है, और यह सबसे अच्छा है जिसे मैं पठनीय बना सकता हूं।

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]"
    }
}

लूप आक्रमणकारी हैं pi = nums[0] * nums[1] *.. nums[i-1]और pj = nums[N-1] * nums[N-2] *.. nums[j+1]iबाईं तरफ के हिस्से "उपसर्ग" तर्क है, और jसही पर भाग "प्रत्यय" तर्क है।


एक-लाइनर की पुनरावृत्ति

जसमीत ने एक (सुंदर!) पुनरावर्ती समाधान दिया; मैंने इसे इस (गुप्त) में बदल दिया है। जावा वन-लाइनर। यह स्टैक में अस्थायी स्थान के साथ इन-प्लेस संशोधन करता हैO(N)

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]"

3
मुझे लगता है कि 2-वैरिएबल लूप को कम से कम समझने में मुश्किल होती है (कम से कम मेरे खराब दिमाग के लिए!), दो अलग-अलग लूप काम भी करेंगे।
गुइलूम

इसलिए मैंने कोड को बाएं / दाएं में अलग किया, यह दिखाने के प्रयास में कि दोनों एक-दूसरे से स्वतंत्र हैं। मुझे यकीन नहीं है कि अगर यह वास्तव में काम करता है, हालांकि =)
पॉलिनेजेल लुब्रिकेंट

15

माइकल एंडरसन के हलस्कल में समाधान का अनुवाद:

otherProducts xs = zipWith (*) below above

     where below = scanl (*) 1 $ init xs

           above = tail $ scanr (*) 1 xs

13

चुपके से "कोई विभाजन नहीं" नियम को दरकिनार:

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

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

2
Nitpick: जहाँ तक मुझे पता है हूँ, कंप्यूटर लघुगणक उनके द्विपद विस्तार का उपयोग लागू - जो करता विभाजन की आवश्यकता होती है ...

10

यहाँ आप 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]);
    }

6

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));

9
विभाजन की अनुमति नहीं है
माइकल एंडरसन

यह अभी भी एक भयानक लग कोड है, हालांकि। डिस्क्लेमर के साथ कि यह डिवीजन का उपयोग करता है, अगर स्पष्टीकरण दिया जाता है तो मैं अभी भी अपवोट करूंगा।
पॉलीजेन लुब्रीकेंट 7

अरे, मैं इस सवाल के माध्यम से पढ़ा नहीं था। : s @polygenel स्नेहक स्पष्टीकरण: विचार इसे दो चरणों में करना है। पहले संख्याओं के पहले अनुक्रम के तथ्य को लें। यही संचय एल्गोरिथ्म करता है (डिफ़ॉल्ट रूप से संख्याओं को जोड़ता है, लेकिन जोड़ को बदलने के लिए कोई अन्य बाइनरी ऑपरेशन ले सकता है, इस मामले में एक गुणा)। इसके बाद मैंने दूसरी बार इनपुट अनुक्रम पर पुनरावृत्त किया, इसे ऐसे रूपांतरित किया कि आउटपुट अनुक्रम में संबंधित तत्व इनपुट अनुक्रम में संबंधित तत्व द्वारा विभाजित पिछले चरण में गणना की गई फैक्टरियल है।
विल्हेमटेल

1
"पहले क्रम का तथ्यात्मक"? WTF? मैं अनुक्रम तत्वों के उत्पाद का मतलब था।
विल्हेमटेल

5
  1. यात्रा वाम-> दायां और बचत उत्पाद रखें। इसे पास्ट कहें। -> ओ (एन)
  2. यात्रा का अधिकार -> बाईं ओर उत्पाद रखें। इसे फ्यूचर कहें। -> ओ (एन)
  3. परिणाम [i] = पिछला [i-1] * भविष्य [i + 1] -> O (n)
  4. विगत [-1] = 1; और भविष्य [एन + 1] = 1;

पर)


3

यहाँ आधुनिक C ++ में मेरा समाधान है। यह उपयोग करता है std::transformऔर याद रखना बहुत आसान है।

ऑनलाइन कोड (वैंडबॉक्स)।

#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 << " "; 
}

2

यह O (n ^ 2) है लेकिन f # सुंदर है:

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) समाधान कभी भी "सुंदर" हैं।
मैड फिजिसिस्ट

2

संख्याओं के उत्पाद को बाईं ओर और प्रत्येक तत्व के दाईं ओर पहले से रखें। हर तत्व के लिए वांछित मूल्य यह निगबोर के उत्पादों का उत्पाद है।

#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;
}

परिणाम:

$ ./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

(अद्यतन: अब मैं करीब से देखता हूं, यह माइकल एंडरसन, डैनियल मिगोवस्की और पॉलीजेनबेलिकेंट के रूप में एक ही विधि का उपयोग करता है)


इस एल्गोरिथ्म का नाम क्या है?
1

1

मुश्किल:

निम्न का उपयोग करें:

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];
}

हां, मुझे यकीन है कि मैं i के बजाय कुछ i-1 से चूक गया, लेकिन इसे हल करने का तरीका सही है।


1

एक O (N ^ (3/2)) गैर-इष्टतम भी है समाधान भी है। यह काफी दिलचस्प है, हालांकि।

पहले आकार N ^ 0.5 के प्रत्येक आंशिक गुणा (यह O (N) समय जटिलता में किया जाता है) को पहले से ही करें। फिर, प्रत्येक संख्या के अन्य-मानों के लिए गणना-एकाधिक को 2 * O (N ^ 0.5) समय में किया जा सकता है (क्यों? क्योंकि आपको केवल अन्य (N ^ 0.5) - 1) संख्याओं के अंतिम तत्वों की आवश्यकता है। और परिणाम ((^ ^ 0.5) - 1) संख्याओं के साथ गुणा करें जो वर्तमान संख्या के समूह से संबंधित हैं)। प्रत्येक संख्या के लिए ऐसा करने से, O (N ^ (3/2)) समय प्राप्त कर सकते हैं।

उदाहरण:

४ ६ 1 २ ३ १ १ ९ ५ 1

आंशिक परिणाम: 4 * 6 * 7 = 168 2 * 3 * 1 = 6 9 * 5 * 8 = 360

3 के मूल्य की गणना करने के लिए, किसी को अन्य समूहों के मूल्यों को 168 * 360 और फिर 2 * 1 के साथ गुणा करना होगा।


1
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);
    }
}

यह समाधान मैं साथ आया था और मुझे यह स्पष्ट लगा कि आप क्या सोचते हैं !?


1
आपके समाधान में O (n ^ 2) समय की जटिलता प्रतीत होती है।
मैड फिजिसिस्ट

1
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] ठेस = [] productify (गिरफ्तारी, ठेस, 0) प्रिंट ठेस


1

यहाँ पूरा होने के लिए स्काला में कोड है:

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

यह निम्नलिखित का प्रिंट आउट लेगा:

120
60
40
30
24

कार्यक्रम मौजूदा हाथी (_! = हाथी) को फ़िल्टर करेगा; और कम सूची विधि के साथ नई सूची गुणा करें। मुझे लगता है कि यह ओ (एन) होगा यदि आप आलसी निकासी के लिए स्कैला दृश्य या Iterator का उपयोग करते हैं।


बहुत सुंदर होने के बावजूद, यह काम नहीं करता है यदि समान मूल्य वाले अधिक तत्व हैं: वैल लिस्ट 1 = सूची (1, 7, 3, 3, 4, 4)
Giordano Scalzo

मैंने मूल्यों को दोहराते हुए कोड का फिर से परीक्षण किया। यह निम्नलिखित 1008 144 112 112 63 63 का उत्पादन करता है मुझे लगता है कि यह दिए गए तत्व के लिए सही है।
बिल्ज

1

बिल्ज़ जवाब के आधार पर - माफ करना मैं टिप्पणी नहीं कर सकता, लेकिन यहां एक स्कैला संस्करण है जो सूची में डुप्लिकेट आइटम को सही ढंग से संभालता है, और शायद ओ (एन) है:

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

रिटर्न:

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

1

अपने जावास्क्रिप्ट समाधान को यहाँ जोड़ने के रूप में मैं किसी को भी यह सुझाव नहीं मिला। विभाजित करने के लिए क्या है, एक संख्या को दूसरी संख्या से निकालने के अलावा, कितनी बार गिन सकते हैं? मैं पूरे एरे के उत्पाद की गणना करने के माध्यम से गया, और फिर प्रत्येक तत्व पर पुनरावृति की, और शून्य तक वर्तमान तत्व को प्रतिस्थापित किया:

//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

मैं 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

हम पहले nums[j](जहां j != i) को सूची से बाहर कर सकते हैं , फिर बाकी का उत्पाद प्राप्त कर सकते हैं ; python wayइस पहेली को हल करने के लिए निम्नलिखित है :

from functools import reduce
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

खैर, इस समाधान को C / C ++ का माना जा सकता है। मान लीजिए कि हमारे पास एक सरणी है "a" जिसमें n तत्व जैसे [n] हैं, तो छद्म कोड नीचे होगा।

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

एक और समाधान, विभाजन का उपयोग करना। दो बार के साथ। सभी तत्वों को गुणा करें और फिर प्रत्येक तत्व द्वारा इसे विभाजित करना शुरू करें।


0
{-
Sqrt (n) सबसेट का उपयोग करके पुनरावर्ती समाधान। O (n) में चलता है।

आकार sqrt (n) के sqrt (n) सबसेट पर समाधान की पुन: गणना करता है। 
फिर प्रत्येक सबसेट के उत्पाद योग पर पुनरावृत्ति करता है।
फिर प्रत्येक सबसेट में प्रत्येक तत्व के लिए, यह उत्पाद के साथ गणना करता है
अन्य सभी उत्पादों का उत्पाद योग।
फिर सभी सबसेट को समतल करता है।

रन समय पर पुनरावृत्ति T (n) = sqrt (n) * T (sqrt (n)) + T (sqrt (n)) + n

मान लीजिए कि O (n) में T (n) n cn है।

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
    + (2 सी + 1) * एन
    N O (n)

ध्यान दें कि एक बाइनरी खोज का उपयोग करके छत (sqrt (n)) की गणना की जा सकती है 
और O (logn) पुनरावृत्तियों, यदि sqrt निर्देश की अनुमति नहीं है।
-}

अन्य उत्पाद [] = []
अन्य उत्पाद [x] = [१]
अन्य उत्पाद [x, y] = [y, x]
अन्य उत्पाद a = fold '(++) [] $ zipWith (\ sp -> नक्शा (* p) s) हल
    कहाँ पे 
      n = लंबाई a

      - सबसेट का आकार। आवश्यकता है कि 1 <s <n।
      s = छत $ sqrt $ fromIntegral n

      solveSubsets = अन्य उत्पाद उप-मानचित्रों को मैप करें
      subsetOtherProducts = अन्य उत्पाद $ मेप उत्पाद उप-उत्पाद

      सबसेट = रिवर्स $ लूप []
          जहाँ लूप [] एसीसी = एसीसी
                लूप ए ए ल = लूप (ड्रॉप सा) ((सा ले): ए सी)

0

यहाँ मेरा कोड है:

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

यहां 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]();
                }
            }

मैं पूरी तरह से निश्चित नहीं हूं कि निर्मित फन की अर्ध-पुनरावृत्ति के कारण यह ओ (एन) है, लेकिन मेरे परीक्षणों से संकेत मिलता है कि यह समय में ओ (एन) है।


0

// यह जावा में पुनरावर्ती समाधान है // मुख्य उत्पाद (ए, 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

O (n) रनटाइम के साथ एक साफ समाधान:

  1. प्रत्येक तत्व के लिए पहले होने वाले सभी तत्वों के उत्पाद की गणना करें और यह एक सरणी "प्री" में संग्रहीत करता है।
  2. प्रत्येक तत्व के लिए उस तत्व के बाद होने वाले सभी तत्वों के उत्पाद की गणना करें और इसे एक "पोस्ट" में संग्रहीत करें
  3. एक तत्व i के लिए एक अंतिम सरणी "परिणाम" बनाएं,

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

1
यह एक ही समाधान के रूप में स्वीकार किए जाते हैं, सही है?
थॉमस अहले

0
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

यहाँ एक और सरल अवधारणा है जो समस्या को हल करती है 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

मेरे पास नीचे दिए गए O(n)स्थान और O(n^2)समय की जटिलता के साथ एक समाधान है ,

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;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.