老但很酷,我自己在一次采访中被问到这个问题并看到了几个解决方案,但这是我最喜欢的,取自
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
等等等等