谜题..求解数组 X 中值的乘积

发布于 2024-09-30 01:41:56 字数 197 浏览 2 评论 0原文

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

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

基本解决方案 - O(n^2) 并且使用除法很容易。但我就是找不到比 O(n^2) 更快的另一种解决方案。

Can you please help me solving this one?

You have an unordered array X of n integers. Find the array M containing n elements where Mi is the product of all integers in X except for Xi. You may not use division. You can use extra memory. (Hint: There are solutions faster than O(n^2).)

The basic ones - O(n^2) and one using division is easy. But I just can't get another solution that is faster than O(n^2).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爱,才寂寞 2024-10-07 01:41:56

left[i]X 中来自 1..i 的所有元素的乘积。令 right[i]X 中来自 i..N 的所有元素的乘积。您可以按以下方式在 O(n) 中计算两者,无需除法:left[i] = left[i - 1] * X[i]右[i] = 右[i + 1] * X[i];

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

注意:left 和 < code>right 是数组。

希望很清楚:)

Let left[i] be the product of all elements in X from 1..i. Let right[i] be the product of all elements in X from i..N. You can compute both in O(n) without division in the following way: left[i] = left[i - 1] * X[i] and right[i] = right[i + 1] * X[i];

Now we will compute M: M[i] = left[i - 1] * right[i + 1]

Note: left and right are arrays.

Hope it is clear:)

输什么也不输骨气 2024-10-07 01:41:56

这是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

Here's a solution in Python. I did the easy way with division to compare against the hard way without. Do I get the job?

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
魔法少女 2024-10-07 01:41:56

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

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

two passes -

 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;
}
滥情空心 2024-10-07 01:41:56

旧但非常酷,我自己在一次采访中被问到这个问题,并看到了几种解决方案,但这是我最喜欢的,取自
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 循环条件本身,而不是主体,直到循环结束才发生
迭代。所以对于
产品[0],
它从 1*1 开始,然后 pi 设置为 120,因此 prods[0] 错过了第一个元素
prods[1], 它是 1 * 120 = 120,然后 pi 被设置为 120*60
等等等等

Old but very cool, I've been asked this at an interview myself and seen several solutions since but this is my favorite as taken from
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;
    }

Here's what's going on, if you write out prods[i] for all the iterations, you'll see the following being calculated

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]

so each prods[i] get hit twice, one from the going from head to tail and once from tail to head, and both of these iterations are accumulating the product as they
traverse towards the center so it's easy to see we'll get exactly what we need, we just need to be careful and see that it misses the element itself and that's where
it gets tricky. the key lies in the

pi *= nums[i++], pj *= nums[j--]

in the for loop conditional itself and not in the body which do not happen until the end of the
iteration. so for
prods[0],
it starts at 1*1 and then pi gets set to 120 after, so prods[0] misses the first elements
prods[1], it's 1 * 120 = 120 and then pi gets set to 120*60 after
so on and so on

同展鸳鸯锦 2024-10-07 01:41:56

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

O(nlogn) approach:

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));
}
水晶透心 2024-10-07 01:41:56

这是我在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

Here is my solution in Python: Easy way but with high computational cost may be?

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文