拼图..解决数组X中值的乘积

时间:2010-10-30 07:27:41

标签: algorithm puzzle

你能帮我解决这个问题吗?

你有一个n个整数的无序数组X.找到包含n个元素的数组M,其中Mi是X中除Xi之外的所有整数的乘积。你可能不会使用除法。你可以使用额外的内存。 (提示:有比O(n ^ 2)快的解决方案。)

基本的 - O(n ^ 2)和使用除法的一个很容易。但我无法得到比O(n ^ 2)更快的另一种解决方案。

6 个答案:

答案 0 :(得分:13)

left[i]成为X 1..i中所有元素的产物。让right[i]成为X i..N中所有元素的乘积。您可以通过以下方式在不O(n)的{​​{1}}中进行计算:left[i] = left[i - 1] * X[i]right[i] = right[i + 1] * X[i];

现在我们将计算MM[i] = left[i - 1] * right[i + 1]

注意:leftright是数组。

希望很明显:)

答案 1 :(得分:1)

这是Python的解决方案。我用分区做了简单的方法来比较没有的困难方式。我能得到这份工作吗?

L = [2, 1, 3, 5, 4]

prod = 1
for i in L: prod *= i
easy = map(lambda x: prod/x, L)
print easy

hard = [1]*len(L)
hmm = 1
for i in range(len(L) - 1):
    hmm *= L[i]
    hard[i + 1] *= hmm
huh = 1
for i in range(len(L) - 1, 0, -1):
    huh *= L[i]
    hard[i - 1] *= huh
print hard

答案 2 :(得分:1)

O(n) - http://nbl.cewit.stonybrook.edu:60128/mediawiki/index.php/TADM2E_3.28

两次通过 -

 int main (int argc, char **argv) {
    int array[] = {2, 5, 3, 4};
    int fwdprod[] = {1, 1, 1, 1};
    int backprod[] = {1, 1, 1, 1};
    int mi[] = {1, 1, 1, 1};
    int i, n = 4;
    for (i=1; i<=n-1; i++) {
        fwdprod[i]=fwdprod[i-1]*array[i-1];
    }
    for (i=n-2; i>=0; i--) {
        backprod[i] = backprod[i+1]*array[i+1];
    }
    for (i=0;i<=n-1;i++) {
        mi[i]=fwdprod[i]*backprod[i]; 
    }
    return 0;
}

答案 3 :(得分:0)

O(nlogn)方法:

int multiply(int arr[], int start, int end) {
    int mid;
    if (start > end) {
        return 1;
    }
    if (start == end) {
        return arr[start];
    }
    mid = (start+end)/2;
    return (multiply(arr, start, mid)*multiply(arr, mid+1, end));
}

int compute_mi(int arr[], int i, int n) {
    if ((i >= n) || (i < 0)) {
        return 0;
    }

    return (multiply(arr, 0, i-1)*multiply(arr, i+1, n-1));
}

答案 4 :(得分:0)

古老但非常酷,我自己在接受采访时被问过这个问题并且看过几个解决方案,但这是我最喜欢的 http://www.polygenelubricants.com/2010/04/on-all-other-products-no-division.html

static int[] products(int... nums) {
       final int N = nums.length;
       int[] prods = new int[N];
       java.util.Arrays.fill(prods, 1);
       for (int // pi----> * <----pj
          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   ;
          System.out.println("pi up to this point is " + pi + "\n");
          System.out.println("pj up to this point is " + pj + "\n");
          System.out.println("prods[i]:" + prods[i] + "pros[j]:" +  prods[j] + "\n");
       }
       return prods;
    }

这是正在发生的事情,如果你为所有迭代写出prods [i],你会看到以下内容被计算

prods[0], prods[n-1]
prods[1], prods[n-2]
prods[2], prods[n-3]
prods[3], prods[n-4]
.
.
.
prods[n-3], prods[2]
prods[n-2], prods[1]
prods[n-1], prods[0]

所以每个prods [i]被击中两次,一次从头到尾,一次从尾到头,这两次迭代都在积累产品,因为它们 走向中心,所以我们很容易看到我们将得到我们需要的东西,我们只需要小心,看到它错过了元素本身,那就是 它变得棘手。关键在于

pi *= nums[i++], pj *= nums[j--]
在for循环条件本身中

而不是在直到结束时才发生的正文中 迭代。因此对于 prods[0], 它从1 * 1开始然后pi设置为120,因此prods [0]错过了第一个元素 prods[1],它是1 * 120 = 120然后pi设置为120 * 60之后 等等等等。

答案 5 :(得分:-1)

这是我在Python中的解决方案:简单的方法却可能需要很高的计算成本?

def product_list(x):
ans = [p for p in range(len(x))]
for i in range(0, len(x)):
    a = 1
    for j in range(0, len(x)):
        if i != j:
            a = a*x[j]
        ans[i] = a
return ans