为了账号安全,请及时绑定邮箱和手机立即绑定

给定一组数字,返回所有其他数字的产品数组(无分区)

给定一组数字,返回所有其他数字的产品数组(无分区)

我在求职面试中被问到这个问题,我想知道其他人如何解决这个问题。我对Java最熟悉,但欢迎使用其他语言的解决方案。给定一组数字,nums返回一个数字数组products,其中products[i]是所有数字的乘积nums[j], j != i。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)不使用除法的情况下这样做。
查看完整描述

3 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

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

通过分别从左边缘和右边缘开始,可以在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];

}

如果你需要在太空中是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];

}


查看完整回答
反对 回复 2019-09-18
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

这是一个小的递归函数(在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;

}


查看完整回答
反对 回复 2019-09-18
?
慕神8447489

TA贡献1780条经验 获得超1个赞

这是我尝试用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]"

    }

}

循环不变量是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]"


查看完整回答
反对 回复 2019-09-18
  • 3 回答
  • 0 关注
  • 653 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信