pol*_*nts 180 arrays algorithm
我在求职面试中被问到这个问题,我想知道其他人如何解决这个问题.我对Java最熟悉,但欢迎使用其他语言的解决方案.
给定一组数字,
nums
返回一个数字数组products
,其中products[i]
是所有数字的乘积nums[j], j != i
.Run Code Online (Sandbox Code Playgroud)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)
不使用除法的情况下执行此操作
Mic*_*son 244
polygenelubricants方法的解释是:诀窍是构造数组(在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, }
Run Code Online (Sandbox Code Playgroud)
通过分别从左边缘和右边缘开始,可以在O(n)中完成这两个操作.
然后将两个数组逐个元素相乘,得到所需的结果
我的代码看起来像这样:
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];
}
Run Code Online (Sandbox Code Playgroud)
如果你需要在太空中是O(1)你也可以这样做(这不太清楚恕我直言)
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];
}
Run Code Online (Sandbox Code Playgroud)
Jas*_*eet 49
这是一个小的递归函数(在C++中)来进行修改.它需要O(n)额外空间(在堆栈上).假设数组在a中并且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;
}
Run Code Online (Sandbox Code Playgroud)
pol*_*nts 16
这是我尝试用Java解决它.抱歉为非标准格式化,但代码有很多重复,这是我能做的最好的,使它可读.
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]"
}
}
Run Code Online (Sandbox Code Playgroud)
循环不变量是pi = nums[0] * nums[1] *.. nums[i-1]
和pj = nums[N-1] * nums[N-2] *.. nums[j+1]
.i
左边的部分是"前缀"逻辑,j
右边的部分是"后缀"逻辑.
Jasmeet给出了一个(漂亮!)递归解决方案; 我把它变成了这个(丑陋的)Java单线程.它使用堆栈中的临时空间进行就地修改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]"
Run Code Online (Sandbox Code Playgroud)
fre*_*low 14
将Michael Anderson的解决方案翻译成Haskell:
otherProducts xs = zipWith (*) below above
where below = scanl (*) 1 $ init xs
above = tail $ scanr (*) 1 xs
Run Code Online (Sandbox Code Playgroud)
sth*_*sth 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]))
Run Code Online (Sandbox Code Playgroud)
小智 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]);
}
Run Code Online (Sandbox Code Playgroud)
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));
Run Code Online (Sandbox Code Playgroud)
小智 5
上)