你能帮我解决这个问题吗?
你有一个n个整数的无序数组X.找到包含n个元素的数组M,其中Mi是X中除Xi之外的所有整数的乘积。你可能不会使用除法。你可以使用额外的内存。 (提示:有比O(n ^ 2)快的解决方案。)
基本的 - O(n ^ 2)和使用除法的一个很容易。但我无法得到比O(n ^ 2)更快的另一种解决方案。
答案 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]
;
现在我们将计算M
:M[i] = left[i - 1] * right[i + 1]
注意:left
和right
是数组。
希望很明显:)
答案 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